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 教程。