我正在製作一個文本編輯器並編輯一個文件我真的需要某種方式來只讀取文件中的某些字節,使用fs.createReadStream
uisng實現start
和end
選項。Node.js v0.10:替換文件中的某些字節而不讀取整個文件
我還需要替換文件中的某些字節。我不確定如何做到這一點。到目前爲止,我提出的最佳解決方案是使用流讀取文件,然後寫入新文件,當遇到要查找的字節時,我會寫入新的內容,從而替換舊的內容新的東西。
這不是最好的方法,因爲你可能知道。要編輯4個字節,我正在讀取一個巨大的2GB文件並寫入2GB(假設我正在編輯一個2GB文件),效率不高。
達到此目的的最佳方法是什麼?我花了兩週的時間來做這件事,我也想過使用緩衝區,但是緩衝區會將整個文件加載到內存中,如果它是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
「是」,我結束了:
yes\n
two\n
three\n
如果我做同樣的,而是fs.write
「Niet的」,我結束了:
niettwo\n
three\n
通知的\n
人物是如何與「T」所取代,這是因爲如何fs.write
作品代表的當在fs.open
中使用r+
時拉緊字節。這是我現在要解決的問題。
一個會如何做這樣的事情「從這個字節到該字節,這些其他字節替換」所以我的功能可能是像function replaceBytes(filePath, newBytes, startByte, endByte)
,並且將取代僅從startByte
到endByte
,無論多久newBytes
,無論是短於還是長於endByte - startByte
的長度。
編輯#3:
OK,我想通了其中的新內容長於被替換舊的內容的情況下。感謝\x00
,我已經能夠弄清楚了。如果新內容和舊內容的長度相同,則不難發現,因爲這裏沒有任何內容。
但是,舊內容比新內容短的情況下,仍然沒有解決。
對於那些好奇,這是舊的內容不是新的內容不再是工作代碼:https://github.com/noedit/file/blob/592a35134440a03d3e3c3e366f6cda7f565c11aa/lib/replaceBytes.js#L27-L34
雖然它擺在那裏,一個空字節這取決於編輯器,它可能會顯示爲一個字符,因此看起來很奇怪。 :/
聽起來好像你在問什麼是不可能的,因爲文件系統不能在文件中間展開和收縮。你有任何跡象表明這是由其他程序完成的嗎? –
@AaronDufour我認爲*用C編寫的文本編輯器之前已經完成了這項工作,否則編輯大文件的效率非常低下......除非所有的文本編輯器都做臨時文件,他們會將整個文件寫入臨時文件,並進行修改,然後rm舊文件和mv新文件到位。或類似的東西。這聽起來令人難以置信的效率不高...... – greduan
C stdlib沒有提供任何可以讓你去做你要求的東西(再一次,因爲文件系統不允許它)。但是,寫入文件可以在後臺完成,因此不應該有任何明顯的影響。 –