我目前正在尝试在将文件保存到本地文件夹之前,找出一种检查本地文件夹是否存在的“正确”方法,这对nodejs文档有些困惑。
fs.exists()已过时,您应该使用fs.stat()或fs.access()。到目前为止一切顺利。
fs.stat():
不建议在调用fs.open(),fs.readFile()或fs.writeFile()之前使用fs.stat()检查文件是否存在。相反,用户代码应直接打开/读取/写入文件,并处理文件不可用时引发的错误。
这表明,我应该尝试编写,捕获错误,创建文件夹,然后重试。即使我正在移动/重命名文件,我也可以,所以我不直接使用提到的三个功能之一。
然后,医生说:
要检查文件是否存在而不随后对其进行操作,建议使用fs.access()。
由于我并没有真正修改文件,而是“仅”修改了文件的内容,因此有人可能会认为这是修改的方法。
但是再说一次,fs.access()文档详细介绍了为什么这也是个坏主意:
不建议在调用fs.open(),fs.readFile()或fs.writeFile()之前使用fs.access()检查文件的可访问性。这样做会引入竞争条件,因为其他进程可能会在两次调用之间更改文件的状态。相反,用户代码应直接打开/读取/写入文件,并处理无法访问文件时引发的错误。
Yadda yadda yadda,已经存在一些相关问题(here或here),但是是否有不超过两年的“最佳实践”的官方信息? >
答案 0 :(得分:6)
我猜该文档建议在以后没有任何操作时使用fs.access
检查文件是否存在,这是因为它是较低级别的简单API,仅用于检查文件访问元数据(包括是否文件是否存在)。一个简单的API可能在性能方面也要好一点,因为它可能只是直接映射到底层本机代码。(注意:我没有做任何基准测试,请以我的观点为依据盐)。
fs.stat
相比, fs.access
提供了更高级别的抽象。它返回文件访问以外的信息。
import {promises as fs} from "fs";
import * as oldfs from "fs";
(async function() {
// fs.stat has higher level abstraction
const stat = await fs.stat(__dirname);
console.log(stat.isDirectory());
console.log(stat.isFile());
console.log(stat.ctime);
console.log(stat.size);
try {
// fs.access is low level API, it throws error when it doesn't match any of the flags
// is dir exists? writable? readable?
await fs.access(__dirname, oldfs.constants.F_OK | oldfs.constants.W_OK | oldfs.constants.R_OK);
} catch (error) {
console.log(`${__dirname} is not exists / writable / readable`);
}
})();
答案 1 :(得分:0)
我认为该文档是不言自明的。
如果您只想检查文件是否存在-不尝试随后打开/读取/写入文件,则应使用access:
// Check if the file exists in the current directory, and if it is writable.
fs.access(file, fs.constants.F_OK | fs.constants.W_OK, (err) => {
if (err) {
console.error(
`${file} ${err.code === 'ENOENT' ? 'does not exist' : 'is read-only'}`);
} else {
console.log(`${file} exists, and it is writable`);
}
});
如果要打开/读取/写入文件,则不应调用access来检查其是否存在,而应直接执行操作并自己处理错误:
//write (NOT RECOMMENDED)
fs.access('myfile', (err) => {
if (!err) {
console.error('myfile already exists');
return;
}
fs.open('myfile', 'wx', (err, fd) => {
if (err) throw err;
writeMyData(fd);
});
});
//write (RECOMMENDED)
fs.open('myfile', 'wx', (err, fd) => {
if (err) {
if (err.code === 'EEXIST') {
console.error('myfile already exists');
return;
}
throw err;
}
writeMyData(fd);
});
这些示例来自您链接的文档。
如果在启动时进行简单检查,还可以使用不推荐使用的existsSync()
-避免在循环中多次使用它,因为这会阻塞nodejs事件循环。 / p>
答案 2 :(得分:0)
尽管我不认为节点支持它,但正确的方法是打开目录以获取dirfd。那应该只使用open,然后才能在dirfd或fd上调用faccess或fstat。 然后,如果打开目录成功,则将dirfd与openat一起使用以打开文件。
我写了一个使用fs.createReadStream的http服务器,如果路径不是文件,则处理该错误。它还使用了暂停和恢复功能,以便能够在流开始传递到响应之前在打开的文件上使用fstat。
答案 3 :(得分:0)
您可以轻松地通过a = np.random.randint(1,101,15)
array([79, 86, 88, 87, 78, 43, 57])
进行同步。
但是,如果您要异步进行操作,只需执行以下操作:
existsSync()
或者将其放在这样的try-catch中...
await fs.promises.access("path");