ZetCode

Dart FileLock

最后修改于 2025 年 4 月 4 日

Dart 中的 FileLock 类提供了文件锁定功能,用于控制对文件的并发访问。它是 Dart 的 dart:io 库的一部分。

FileLock 有助于防止多个进程或隔离访问同一文件时发生竞态条件。它支持共享和独占锁定模式。

基本定义

FileLock 是一个枚举,代表不同类型的文件锁。它与文件操作一起使用,以控制对文件资源的并发访问。

该枚举有三个值:FileLock.sharedFileLock.exclusiveFileLock.blocking。这些值控制如何获取和释放锁。

基本文件锁定

此示例展示了使用独占锁进行基本文件锁定。

main.dart
import 'dart:io';

void main() async {
  var file = File('test.txt');
  
  // Open the file for writing with exclusive lock
  var raf = await file.open(mode: FileMode.write, 
    lock: FileLock.exclusive);
  
  // Write to the file
  await raf.writeString('Locked content\n');
  
  // Release the lock by closing the file
  await raf.close();
  
  print('File written with exclusive lock');
}

我们以独占锁模式打开文件,阻止其他进程访问它。在文件关闭时,锁会自动释放。

$ dart main.dart
File written with exclusive lock

共享文件锁

此示例演示了如何使用共享锁进行并发读取。

main.dart
import 'dart:io';

void main() async {
  var file = File('test.txt');
  
  // Open with shared lock for reading
  var raf1 = await file.open(mode: FileMode.read, 
    lock: FileLock.shared);
  var raf2 = await file.open(mode: FileMode.read, 
    lock: FileLock.shared);
  
  // Both can read simultaneously
  print(await raf1.readAsString());
  print(await raf2.readAsString());
  
  await raf1.close();
  await raf2.close();
}

共享锁允许多个读取器同时访问文件。它们可以防止在活动期间获取独占锁。

$ dart main.dart
Locked content
Locked content

阻塞锁

此示例展示了如何使用阻塞锁来等待访问。

main.dart
import 'dart:io';

void main() async {
  var file = File('test.txt');
  
  // First process gets exclusive lock
  var raf1 = await file.open(mode: FileMode.write, 
    lock: FileLock.exclusive);
  
  // Second process waits for lock to be released
  Future.delayed(Duration(seconds: 2), () async {
    var raf2 = await file.open(mode: FileMode.write, 
      lock: FileLock.blockingExclusive);
    await raf2.writeString('Second write\n');
    await raf2.close();
    print('Second write completed');
  });
  
  // First process writes and releases lock
  await raf1.writeString('First write\n');
  await Future.delayed(Duration(seconds: 3));
  await raf1.close();
  print('First write completed');
}

阻塞锁会等待当前锁释放后再继续。这可以防止由于锁获取失败而产生的错误。

$ dart main.dart
First write completed
Second write completed

锁冲突

此示例演示了锁冲突发生时的情况。

main.dart
import 'dart:io';

void main() async {
  var file = File('test.txt');
  
  try {
    // First exclusive lock
    var raf1 = await file.open(mode: FileMode.write, 
      lock: FileLock.exclusive);
    
    // Try to get another exclusive lock (will fail)
    var raf2 = await file.open(mode: FileMode.write, 
      lock: FileLock.exclusive);
    
    await raf1.close();
    await raf2.close();
  } catch (e) {
    print('Lock conflict: $e');
  }
}

当发生锁冲突时,会抛出异常。这有助于检测和处理应用程序中的并发访问问题。

$ dart main.dart
Lock conflict: FileSystemException: Cannot open file, path = 'test.txt' (OS Error: The process cannot access the file because it is being used by another process., errno = 32)

带超时的文件锁

此示例使用 Future.any 实现带超时的锁。

main.dart
import 'dart:io';
import 'dart:async';

void main() async {
  var file = File('test.txt');
  
  // Get initial exclusive lock
  var raf1 = await file.open(mode: FileMode.write, 
    lock: FileLock.exclusive);
  
  // Try to get lock with timeout
  try {
    var result = await Future.any([
      file.open(mode: FileMode.write, lock: FileLock.exclusive),
      Future.delayed(Duration(seconds: 2),
    ]);
    
    if (result is RandomAccessFile) {
      print('Lock acquired');
      await result.close();
    } else {
      print('Timeout waiting for lock');
    }
  } finally {
    await raf1.close();
  }
}

我们实现了锁获取的超时机制。如果在 2 秒内未获取锁,我们将适当地处理超时情况。

$ dart main.dart
Timeout waiting for lock

最佳实践

来源

Dart FileLock 文档

本教程通过实际示例介绍了 Dart 的 FileLock 类,展示了基本用法、锁类型、冲突处理和超时模式。

作者

我叫 Jan Bodnar,是一名充满热情的程序员,拥有丰富的编程经验。我自 2007 年以来一直在撰写编程文章。迄今为止,我已撰写了 1,400 多篇文章和 8 本电子书。我在教授编程方面拥有超过十年的经验。

列出 所有 Dart 教程