节点js在复制之前检查文件是否打开
Node js check if a file is open before copy
在将文件复制到另一个文件之前,我需要检查文件是否已打开 location.The 下面的代码告诉它打开时是否出现错误代码 = EBUSY。但如果文件未打开,它会删除文件的内容。有没有更好的方法来获取这些信息。
fs.open('my-file.dwg','w', function(err,data) {
});
在我看来你可以使用 r+
:
fs.open('my-file.dwg','r+', function(err,data) {
});
来自 fs
模块文档:
'r+' - Open file for reading and writing. An exception occurs if the
file does not exist.
如果文件已经被其他人打开,那么它不应该授予您读写权限并且应该 return 一个错误。如果文件不存在,这将不会创建它。
r+
选项不会像 w+
选项那样截断或创建文件。
警告:我发布这个是因为接受的答案不起作用。然而,我不是 Windows 文件锁定方面的专家,但这是我能够拼凑的:
在 Windows 上似乎有 3 种类型的锁导致 Node 中的 EBUSY
。
- 文件锁定 'exclusive lock'
- 例如当您在 MS Word 中打开文档时
- 在 Windows Fileapi.h 中,这些是用 CreateFileW(dwShareMode:0) and LockFileEx(dwFlags)
创建的
- 被 OS 锁定的可执行文件,目前正在 运行ning
- 例如当你 运行
setup.exe
- 系统保护文件
- 例如
C:\hiberfil.sys
选项A:
Node fs 建立在 libuv 之上,允许传递高级选项来请求独占锁。这似乎
是最安全的技术,因为没有机会 changing/corrupting 文件。
用UV_FS_O_RDONLY and UV_FS_O_EXLOCK
打开文件
1、2 和 3 返回 EBUSY。
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()
也可靠地失败,不需要任何 OS 特定标志,但更危险,因为您可能会在文件实际移动时引入竞争条件错误暂时。
1、2 和 3 返回 EBUSY。
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 的文件不起作用,不会返回任何错误。
2 和 3 返回 EBUSY。
try {
await fs.promises.open(filePath, 'r+');
} catch (error) {
if (error.code === 'EBUSY'){
console.log('file is busy');
} else {
throw error;
}
}
在将文件复制到另一个文件之前,我需要检查文件是否已打开 location.The 下面的代码告诉它打开时是否出现错误代码 = EBUSY。但如果文件未打开,它会删除文件的内容。有没有更好的方法来获取这些信息。
fs.open('my-file.dwg','w', function(err,data) {
});
在我看来你可以使用 r+
:
fs.open('my-file.dwg','r+', function(err,data) {
});
来自 fs
模块文档:
'r+' - Open file for reading and writing. An exception occurs if the file does not exist.
如果文件已经被其他人打开,那么它不应该授予您读写权限并且应该 return 一个错误。如果文件不存在,这将不会创建它。
r+
选项不会像 w+
选项那样截断或创建文件。
警告:我发布这个是因为接受的答案不起作用。然而,我不是 Windows 文件锁定方面的专家,但这是我能够拼凑的:
在 Windows 上似乎有 3 种类型的锁导致 Node 中的 EBUSY
。
- 文件锁定 'exclusive lock'
- 例如当您在 MS Word 中打开文档时
- 在 Windows Fileapi.h 中,这些是用 CreateFileW(dwShareMode:0) and LockFileEx(dwFlags) 创建的
- 被 OS 锁定的可执行文件,目前正在 运行ning
- 例如当你 运行
setup.exe
- 例如当你 运行
- 系统保护文件
- 例如
C:\hiberfil.sys
- 例如
选项A:
Node fs 建立在 libuv 之上,允许传递高级选项来请求独占锁。这似乎 是最安全的技术,因为没有机会 changing/corrupting 文件。
用UV_FS_O_RDONLY and UV_FS_O_EXLOCK
打开文件1、2 和 3 返回 EBUSY。
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()
也可靠地失败,不需要任何 OS 特定标志,但更危险,因为您可能会在文件实际移动时引入竞争条件错误暂时。
1、2 和 3 返回 EBUSY。
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 的文件不起作用,不会返回任何错误。
2 和 3 返回 EBUSY。
try {
await fs.promises.open(filePath, 'r+');
} catch (error) {
if (error.code === 'EBUSY'){
console.log('file is busy');
} else {
throw error;
}
}