我有一个本地JSON文件,我打算从NodeJS电子应用程序读取/写入。我不确定,但是我相信应该使用FileHandle来避免多次打开和关闭操作,而不是使用readFile()和writeFile()。因此,我试图从fs.promises.open()中获取FileHandle,但问题似乎是我无法从现有文件中获取FileHandle,而无需截断并将其清除为0。
const { resolve } = require('path');
const fsPromises = require('fs').promises;
function init() {
// Save table name
this.path = resolve(__dirname, '..', 'data', `test.json`);
// Create/Open the json file
fsPromises
.open(this.path, 'wx+')
.then(fileHandle => {
// Grab file handle if the file don't exists
// because of the flag 'wx+'
this.fh = fileHandle;
})
.catch(err => {
if (err.code === 'EEXIST') {
// File exists
}
});
}
我做错什么了吗?有更好的方法吗?
链接:https://nodejs.org/api/fs.html#fs_fspromises_open_path_flags_modehttps://nodejs.org/api/fs.html#fs_file_system_flags
因为JSON是一种文本格式,必须立即读取或写入所有文本,并且无法轻松地对其进行修改或添加到适当的位置,所以您将不得不一次读取整个文件或写入整个文件。
因此,最简单的选择是只使用fs.promises.readFile()
和fs.promises.writeFile()
,然后让库打开文件,读取/写入文件并关闭文件。在现代操作系统中打开和关闭文件要利用磁盘缓存,因此,如果您要重新打开不久前刚刚打开的文件,这将不是一个缓慢的操作。此外,由于nodejs在libuv中的辅助线程中执行这些操作,因此它也不会阻塞nodejs的主线程,因此它通常不会对服务器造成性能问题。
如果您真的想一次打开文件并保持打开状态,则可以使用r+
标志将其打开以进行读取和写入,如下所示:
const fileHandle = await fsPromises.open(this.path, 'r+');
读取整个文件很简单,因为新的fileHandle对象具有.readFile()
方法。
const text = await fileHandle.readFile({encoding 'utf8'});
要从打开的文件句柄写入整个文件,您必须截断文件,然后写入字节,然后刷新写入缓冲区,以确保数据的最后一位到达磁盘且不位于缓冲区中。
await fileHandle.truncate(0); // clear previous contents
let {bytesWritten} = await fileHandle.write(mybuffer, 0, someLength, 0); // write new data
assert(bytesWritten === someLength);
await fileHandle.sync(); // flush buffering to disk