简体   繁体   English

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

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

I'm having trouble working out why Windows is creating a new file with the read-only attribute set.我无法弄清楚为什么 Windows 使用只读属性集创建新文件。 What I want is exclusive random-access write permissions to a file that I'll be using as a simple file-based data store.我想要的是对我将用作简单的基于文件的数据存储的文件的独占随机访问写入权限。 I'm fine with other processes reading from it, but I only want a single process to be able to write to it.我对其他进程从它读取数据没问题,但我只希望一个进程能够写入它。

I've tried several different variations of the open flags, but no matter what I do, Windows seems to be setting a read-only attribute on the file .我已经尝试了打开标志的几种不同变体,但无论我做什么,Windows 似乎都在文件上设置了只读属性 As such, after closing the file, attempts to reopen it for writing fail .因此,在关闭文件后,尝试重新打开它以写入失败 I understand that I could manually try to manipulate the attribute after the fact, but this is backwards.我知道我可以在事后手动尝试操作属性,但这是倒退的。 I don't want the attribute to appear in the first place.我不希望该属性首先出现。 When I close the file, it should be safe for someone else to open for writing.当我关闭文件时,其他人打开进行写入应该是安全的。

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

Output:输出:

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'
}

不需要的只读属性

As you can see, the file seems to have the read-only attribute set, even after the file is closed.如您所见,文件似乎设置了只读属性,即使在文件关闭之后也是如此。

The file mode argument 6 is creating a read only file. 文件mode参数6正在创建一个只读文件。

Use 0o600 if you want read/write for the user.如果您想为用户读/写,请使用0o600

TLDR: Set the file mode to 0o644 so you can read and write to it, but others can only read. TLDR:将文件模式设置为0o644这样你就可以对其进行读写,但其他人只能读取。 Setting the value to just 6 does not give you (the owner of the file) any read or write permissions and thus the EPERM issue you run into when you try to open it yourself after creating it.将该值设置为6不会给您(文件的所有者)任何读取或写入权限,因此您在创建它后尝试自己打开它时会遇到 EPERM 问题。

It looks to me like your file mode values are not correct.在我看来,您的文件模式值不正确。 When you set it to 6 , that defines read and write for others, but does not define read and write for yourself.当您将其设置为6 ,它定义了其他人的读写,但不定义自己的读写。

There's a pretty good description of how they work here .对它们在这里的工作方式有很好的描述。

You basically want three octal values.您基本上需要三个八进制值。 The left most one is for you (the owner).最左边的一个是给你的(主人)。 The middle one is for the group.中间的是一组。 The right one is for others.正确的是别人。 So, 0o644 gives you the owner read and write and group and others only read.因此, 0o644为您提供所有者读写和组和其他人只读。

As a test harness to try different modes, I used this program:作为尝试不同模式的测试工具,我使用了这个程序:

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

FYI, node.js has named constants for the different permissions which might make the code more readable in the long run than just using octal digits.仅供参考,node.js 为不同的权限命名了常量,从长远来看,这可能会使代码比仅使用八进制数字更具可读性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM