【问题标题】:Node js check if a file is open before copyNode js在复制之前检查文件是否打开
【发布时间】:2015-04-19 18:06:54
【问题描述】:

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

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

    });

【问题讨论】:

标签: javascript node.js fs


【解决方案1】:

在我看来你可以使用r+

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

});

来自fs 模块文档:

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

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

r+ 选项不会像 w+ 选项那样截断或创建文件。

【讨论】:

    【解决方案2】:

    警告:我发布这个是因为接受的答案不起作用。但是,我不是 Windows 文件锁定方面的专家,但这是我能够拼凑起来的:

    在 Windows 上似乎有 3 种类型的锁会导致 Node 中的 EBUSY

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

    选项 A:

    Node 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;
      }
    }
    

    【讨论】:

    • 我使用了选项A。但它在notepad++前不起作用
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-02
    • 1970-01-01
    • 2023-04-10
    • 1970-01-01
    • 2019-03-30
    相关资源
    最近更新 更多