Node.js、Windows、fs.open() - 新创建文件上不需要的只读标志

Node.js, Windows, fs.open() - unwanted read-only flag on newly-created file

我无法理解为什么 Windows 正在创建一个设置了只读属性的新文件。我想要的是对我将用作简单的基于文件的数据存储的文件的独占随机访问写入权限。我可以接受其他进程从中读取,但我只希望单个进程能够写入它。

我尝试了几种不同的打开标志变体,但是 无论我做什么,Windows 似乎都在文件上设置只读属性.因此,关闭文件后,尝试重新打开它写入失败。我知道我可以在事后手动尝试操作该属性,但这是倒退的。我不希望属性出现在第一位。当我关闭文件时,其他人打开进行写入应该是安全的。

FS.open(filePath + '.lock', 'w+', 6, (err, fd) => {
  if (err) console.log('failed to open lock file', err);
  else {
    console.log('successfully opened lock file');
    setTimeout(() => {
      FS.close(fd, () => {
        console.log(`closed lock file`);
        setTimeout(() => {
          console.log(`attempt reopening the file...`);
          FS.open(filePath + '.lock', 'w+', 6, (err, fd) => {
            if (err) console.log('failed to open lock file', err);
            else {
              console.log(`file closed successfully`);
              FS.closeSync(fd);
            }
          });
        }, 500);
      });
    }, 500);
  }
});

输出:

successfully opened lock file
closed lock file
attempt reopening the file...
failed to open lock file [Error: EPERM: operation not permitted, open 'D:\salix\test.data.lock'] {
  errno: -4048,
  code: 'EPERM',
  syscall: 'open',
  path: 'D:\dev\test.data.lock'
}

如您所见,文件似乎设置了只读属性,即使在文件关闭后也是如此。

file mode 参数 6 正在创建一个只读文件。

如果您希望用户 read/write,请使用 0o600

TLDR:将文件模式设置为0o644,这样您就可以对其进行读写,而其他人只能读取。将值设置为 6 不会给你(文件的所有者)任何读取或写入权限,因此当你在创建它后尝试自己打开它时,EPERM 问题你 运行 。

在我看来,您的文件模式值不正确。当你设置为6时,就是给别人定义读写,不给自己定义读写。

对它们的工作原理有很好的描述here

您基本上需要三个八进制值。最左边的一个是给你(所有者)的。中间一个是给小组的。正确的是给别人的。所以,0o644 给你所有者读写和组,其他人只读。

作为尝试不同模式的测试工具,我使用了这个程序:

const fs = require('fs');
const fsp = fs.promises;

function delay(t) {
    return new Promise(resolve => {
        setTimeout(resolve, t);
    });
}

async function run() {
    const mode = 0o644;
    const fileHandle1 = await fsp.open("test.lock", "w+", mode);
    console.log("file open first time");
    await fileHandle1.close();
    console.log("file closed first time");

    await delay(500);

    const fileHandle2 = await fsp.open("test.lock", "w+", mode);
    console.log("file open second time");
    await fileHandle2.close();
    console.log("file closed second time");
}

run().then(result => {
    console.log("done");
}).catch(err => {
    console.log(err);
});

仅供参考,node.js 具有 named constants 的不同权限,这可能使代码在长 运行 中比仅使用八进制数字更具可读性。