节点js在复制之前检查文件是否打开

时间:2015-02-18 16:32:11

标签: javascript node.js fs

我需要在将文件复制到另一个位置之前检查文件是否打开。下面的代码告诉它是否打开,错误代码= EBUSY。但如果文件未打开,则会删除文件的内容。有没有更好的方法来实现这些信息。

    fs.open('my-file.dwg','w', function(err,data) {

    });

2 个答案:

答案 0 :(得分:2)

在我看来,您可以使用r+

fs.open('my-file.dwg','r+', function(err,data) {

});

来自fs模块文档:

  

'r +' - 打开文件进行读写。如果是,则发生异常   文件不存在。

如果该文件已被其他人打开,则它不应授予您读写权限,并应返回错误。如果不存在,则不会创建文件。

r+选项不会截断或创建w+选项之类的文件。

答案 1 :(得分:0)

注意事项:我将其发布为接受的答案不起作用。但是我不是Windows文件锁定方面的专家,但这是我能够解决的问题:

在Windows上,似乎有3种类型的锁导致了节点EBUSY

  1. 以“排他锁”锁定的文件
  2. 当前由操作系统锁定的可执行文件
    • 例如当您运行setup.exe
  3. 系统保护的文件
    • 例如C:\hiberfil.sys

选项A:

节点fs建立在libuv上,它允许传递高级选项来请求排他锁。好像 是最安全的技术,因为没有机会更改/损坏文件。

使用UV_FS_O_RDONLYUV_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;
  }
}