我正在制作一个文本编辑器,为了编辑文件,我确实需要某种方法来仅从文件中读取某些字节,这是我使用的实现的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
尽管它确实在其中放置了一个空字节,这取决于编辑器,但它可能会显示为字符,因此看起来很奇怪。 :/