Dart FileLock
最后修改于 2025 年 4 月 4 日
Dart 中的 FileLock
类提供了文件锁定功能,用于控制对文件的并发访问。它是 Dart 的 dart:io
库的一部分。
FileLock 有助于防止多个进程或隔离访问同一文件时发生竞态条件。它支持共享和独占锁定模式。
基本定义
FileLock
是一个枚举,代表不同类型的文件锁。它与文件操作一起使用,以控制对文件资源的并发访问。
该枚举有三个值:FileLock.shared
、FileLock.exclusive
和 FileLock.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
最佳实践
- 范围: 保持锁的持续时间尽可能短
- 顺序: 以一致的顺序获取锁以防止死锁
- 清理: 始终在 finally 块中释放锁
- 粒度: 使用适当的锁类型(共享/独占)
- 超时: 为阻塞操作实现超时
来源
本教程通过实际示例介绍了 Dart 的 FileLock 类,展示了基本用法、锁类型、冲突处理和超时模式。
作者
列出 所有 Dart 教程。