我的目标是在NodeJS中替换文件中特定位置的值,而不将文件的全部内容加载到RAM(而不是fs.readFileSync(path, "utf8")
(中。它应该适用于非常大的文件(> 2^28 - 16
字节(V8允许的最大字符串长度((。
这是我的代码:
const fs = require('fs');
const path = "./text.txt";
const cursor = 1;
(async () => {
await new Promise((res, rej) => {
const buffer = Buffer.from('ee');
fs.open(path, 'w+', function (err, fd) {
if (err) {
console.log('Cant open file');
rej()
} else {
fs.write(fd, buffer, 0, buffer.length, cursor, function (err, writtenbytes) {
if (err) {
console.log('Cant write to file');
rej()
} else {
console.log(writtenbytes +
' characters added to file');
res()
}
})
}
})
})
})()
这是我启动程序之前"./text.txt"
的内容:
foo
这是我启动程序后"./text.txt"
的内容:
❓ee
和的charCode❓等于0。
这是预期的结果:
fee
怎么了?我应该修复什么?
问题是打开文件时使用w+
作为模式。应该是r+
:
fs.open(path, 'r+', function (err, fd) {
// −−−−−−−−−−−−^^
来自文件:
'w+'
:打开文件进行读写。文件被创建(如果不存在(或被截断(如果存在(。
(我的重点(
因此,一旦它被截断,写入位置1就在位置0
隐式写入0
(要么是这样,要么在那里留下了不确定的垃圾,我不确定它是指定的(。
但使用r+
:
'r+'
:打开文件进行读写。如果文件不存在,则会发生异常。
。。。您可以在不截断的情况下打开现有文件,然后可以写入到特定位置。
值得一提的是,如果您正在使用async
函数,您可能需要使用fs
API(fs.promises
(的promise版本:
const fsp = require("fs").promises;
const path = "./text.txt";
const cursor = 1;
(async () => {
const handle = await fsp.open(path, "r+");
const buffer = Buffer.from('ee');
console.log(buffer);
try {
const { bytesWritten } = await handle.write(buffer, 0, buffer.length, cursor);
console.log(`${bytesWritten} characters added to file`);
} catch (err) {
console.log(`Cant write to file: ${err.message || String(err)}`);
} finally {
handle.close();
}
})()
.catch(err => {
console.log(`Error: ${err.message || String(err)}`);
});
还要注意,您希望捕获顶级async
函数可能抛出的promise的拒绝。