节点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

  1. 文件锁定 'exclusive lock'
  2. 被 OS 锁定的可执行文件,目前正在 运行ning
    • 例如当你 运行 setup.exe
  3. 系统保护文件
    • 例如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;
  }
}