Node.js v0.10:替换文件中的某些字节而不读取整个文件

2023-11-24

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

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

正如您可能知道的那样,这不是最好的方法。为了编辑 4 个字节,我正在读取一个巨大的 2GB 文件并写入 2GB(假设我正在编辑一个 2GB 文件),效率很低。

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

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

如果这样做并不简单,那么从文件中删除某些字节而不读取整个文件怎么样?如果我能做到这一点,那么我可以删除要替换的字节并使用类似的东西fs.write()添加我想要替换的内容。

Edit #1:

经过一番尝试后,我发现如果我用以下命令打开文件fs.open有旗帜r+进而fs.write that replaces东西。所以如果文本是“Lorem ipsum”并且我fs.write“!!!”结果将是“!!!m ipsum”。

如果我要写的所有内容都是完美的长度,那就可以了。 :/

我知道如果新内容的长度不理想该怎么办,但我不知道该怎么做。 :/也许如果有某种“空字节”......

Edit #2:

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

one\n
two\n
three\n

If I fs.open在字节 0 然后fs.write“是的”,我最终得到:

yes\n
two\n
three\n

如果我做同样的事情,但相反fs.write“niet”,我最终得到:

niettwo\n
three\n

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

如何去做类似“从这个字节到这个字节,用这些其他字节替换它”这样的事情,所以我的函数可能是这样的function replaceBytes(filePath, newBytes, startByte, endByte)这只会取代startByte to endByte,无论多久newBytes,无论它比长度短还是长endByte - startByte.

Edit #3:

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

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

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

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


正如你所发现的,fs.write with r+模式允许您覆盖字节。这足以满足添加和删除的片段长度完全相同的情况。

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

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

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

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Node.js v0.10:替换文件中的某些字节而不读取整个文件 的相关文章

随机推荐