如何覆盖 NodeJS 文件中的特定位置?

How to overwrite at a specific position in a file in 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) {
// −−−−−−−−−−−−^^

来自 the documentation:

'w+': Open file for reading and writing. The file is created (if it does not exist) or truncated (if it exists).

(我的重点)

所以一旦它被截断,写入位置 1 隐含地在位置 0 写入 0(或者那个,或者在那里留下不确定的垃圾,我不确定它指定的是哪个)。

但是 r+:

'r+': Open file for reading and writing. An exception occurs if the file does not exist.

...你打开现有文件而不截断,然后可以写入特定位置。


就其价值而言,如果您使用的是 async 函数,则可能需要使用 fs API (fs.promises) 的承诺版本:

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

另请注意,您希望捕获对 top-level async 函数可能抛出的承诺的拒绝。