如何在NodeJS中的文件中的特定位置进行覆盖



我的目标是在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函数,您可能需要使用fsAPI(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的拒绝。

最新更新