Node.js v0.10 : Replace certain bytes in file without reading whole file

标签 node.js file-io

我正在制作一个文本编辑器,为了编辑一个文件,我真的需要某种方法来只从文件中读取某些字节,这是我使用 fs.createReadStream 实现的。使用 startend选项。

我还需要替换文件中的某些字节。我不确定如何做到这一点。到目前为止,我提出的最佳解决方案是使用流读取文件,然后写入新文件,当我遇到要查找的字节时,我改为写入新内容,从而将旧内容替换为新东西。

这不是最好的方法,您可能知道。要编辑 4 个字节,我正在读取一个巨大的 2GB 文件并写入 2GB(假设我正在编辑一个 2GB 文件),至少效率不高。

实现这一目标的最佳方法是什么?我花了两周时间这样做,我也想过使用 Buffers,但是 Buffers 将整个文件加载到内存中,如果它是 2GB 的文件,这又是低效的。

如何在不读取整个文件且不安装一些具有 C++ 代码的 npm 包的情况下替换文件中的某些字节。我不希望我的编辑器必须编译 C++ 代码。

如果这样做并不简单,那么在不读取整个文件的情况下从文件中删除某些字节怎么样?如果我可以这样做,那么我可以删除要替换的字节并使用类似 fs.write() 的内容。添加我希望它们被替换的那些。

编辑 #1:

玩了之后,我发现如果我用 fs.open 打开一个文件带旗r+然后 fs.write那取代了东西。所以如果文本是“Lorem ipsum”而我 fs.write “!!!!”结果将是“!!!!!!m ipsum”。

如果只有我要写的所有东西都是完美的长度,这会很好用。 :/

我知道在新内容不是完美长度的情况下该怎么做,但我不知道该怎么做。 :/也许如果有某种“空字节”......

编辑 #2:

如上所述,fs.open (带有 r+ 标志选项)+ fs.write允许我在不读取整个文件的情况下覆盖文件中的内容,这太棒了。现在有了这个,我遇到了一个新问题。让我们获取以下文件:

one\n
two\n
three\n

如果我 fs.open在字节 0 然后 fs.write "is",我最终得到:
yes\n
two\n
three\n

如果我做同样的事情而不是 fs.write “niet”,我最终得到:
niettwo\n
three\n

注意 \n字符被替换为“t”,这是因为 fs.write使用 r+ 时通过替换字节来工作在 fs.open .这是我现在正在努力解决的问题。

人们将如何做诸如“从这个字节到这个字节,用这些其他字节替换它”之类的事情,所以我的函数可能类似于 function replaceBytes(filePath, newBytes, startByte, endByte)这将仅替换来自 startByteendByte ,不管多久newBytes ,无论是比endByte - startByte的长度短还是长.

编辑 #3:

好的,我想出了新内容比被替换的旧内容长的情况。感谢 \x00 ,我已经能够弄清楚了。如果新旧内容的长度相同,这不难弄清楚,因为那里没有什么可做的。

但是旧内容比新内容短的情况,仍然没有解决。

对于那些好奇的人,这是旧内容比新内容长的工作代码:https://github.com/noedit/file/blob/592a35134440a03d3e3c3e366f6cda7f565c11aa/lib/replaceBytes.js#L27-L34

尽管它确实在其中放置了一个空字节,这取决于编辑器,但它可能会显示为一个字符,因此看起来很奇怪。 :/

最佳答案

正如您所发现的,fs.writer+模式允许您覆盖字节。这对于添加和删除的片段长度完全相同的情况就足够了。

添加的文本比删除的文本短时,建议不要填写\x00字节,正如您在其中一项编辑中所建议的那样。这些在大多数类型的文件中都是完全有效的字符(在源代码中,它们通常会导致编译器/解释器抛出错误)。

简短的回答是,这通常是不可能的。这不是抽象问题;在文件系统级别,文件存储在连续字节的块中。没有从文件中间插入/删除的通用方法。

执行此操作的正确方法是查找您需要更改的第一个字节,然后写入文件的其余部分(除非您达到添加/删除相同字节数的点,在这种情况下你可以停止写作)。

为了避免在长时间写入或类似情况下崩溃的问题,通常先写入临时文件位置,然后 mv临时文件代替您要保存的实际文件。

关于Node.js v0.10 : Replace certain bytes in file without reading whole file,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30768630/

相关文章:

javascript - 在尝试抓取 React 网站时获取 index.html 内容

node.js - NodeJS Async/Await - 使用 API 调用构建配置文件

javascript - 为什么应用 JSON.stringify 会占用这么多内存?

无法将双数正确导入到 C 程序中

c++ - 如何将文本文件读入二维数组 - C++

java - 为什么我无法将所有行导出到文本文件?

c# - 如何在创建文件夹时移动文件。目录.方法等

node.js - 尝试 "npm ERR! code ENOENT"`npm run build `` 后如何解决 npm 错误 ```

python - 如何从给定文件中读取矩阵?

javascript - 使用循环重新声明全局范围内定义的变量