警告:我发布这个是因为接受的答案不起作用。但是,我不是 Windows 文件锁定方面的专家,但这是我能够拼凑起来的:
在 Windows 上似乎有 3 种类型的锁会导致 Node 中的 EBUSY。
- 使用“排他锁”锁定的文件
- 被当前运行的操作系统锁定的可执行文件
- 系统保护文件
选项 A:
Node fs 建立在libuv 之上,它允许传递高级选项来请求独占锁。这似乎
成为最安全的技术,因为不会更改/损坏文件。
用UV_FS_O_RDONLY和UV_FS_O_EXLOCK打开文件
EBUSY 为 1、2 和 3 返回。
try {
const fileHandle = await fs.promises.open(filePath, fs.constants.O_RDONLY | 0x10000000);
fileHandle.close();
} catch (error) {
if (error.code === 'EBUSY'){
console.log('file is busy');
} else {
throw error;
}
}
注意:这需要 libuv >= 1.17.0,NodeJS 满足 >= 8.10.0
选项 B:
在锁定文件上执行fs.rename() 也会可靠地失败,不需要任何特定于操作系统的标志,但更危险,因为您可能会在文件实际临时移动时引入竞争条件错误。
EBUSY 为 1、2 和 3 返回。
try {
await fs.promises.rename(filePath, filePathNew);
await fs.promises.rename(filePathNew, filePath);
} catch (error) {
if (error.code === 'EBUSY'){
console.log('file is busy');
} else {
throw error;
}
}
选项 C(不要使用):
执行fs.open(..., 'r+')。对于具有排他锁 1 的文件,这不起作用,不会返回错误。
EBUSY 为 2 和 3 返回。
try {
await fs.promises.open(filePath, 'r+');
} catch (error) {
if (error.code === 'EBUSY'){
console.log('file is busy');
} else {
throw error;
}
}