在 NodeJS 中,我們對文件的操作需要依賴核心模塊 fs , fs 中有很基本 API 可以幫助我們讀寫占用內(nèi)存較小的文件,如果是大文件或內(nèi)存不確定也可以通過 open 、 read 、 write 、 close 等方法對文件進(jìn)行操作,但是這樣操作文件每一個(gè)步驟都要關(guān)心,非常繁瑣, fs 中提供了可讀流和可寫流,讓我們通過流來操作文件,方便我們對文件的讀取和寫入。
可讀流
1、createReadStream 創(chuàng)建可讀流
createReadStream 方法有兩個(gè)參數(shù),第一個(gè)參數(shù)是讀取文件的路徑,第二個(gè)參數(shù)為 options 選項(xiàng),其中有八個(gè)參數(shù):
rnullnull0o666true64 * 1024
createReadStream 的返回值為 fs.ReadStream 對象,讀取文件的數(shù)據(jù)在不指定 encoding 時(shí),默認(rèn)為 Buffer。
let fs = require("fs");// 創(chuàng)建可讀流,讀取 1.txt 文件let rs = fs.creatReadStream("1.txt", { start: 0, end: 3, highWaterMark: 2});在創(chuàng)建可讀流后默認(rèn)是不會讀取文件內(nèi)容的,讀取文件時(shí),可讀流有兩種狀態(tài),暫停狀態(tài)和流動狀態(tài)。
注意:本篇的可寫流為流動模式,流動模式中有暫停狀態(tài)和流動狀態(tài),而不是暫停模式,暫停模式是另一種可讀流 readable 。
2、流動狀態(tài)
流動狀態(tài)的意思是,一旦開始讀取文件,會按照 highWaterMark 的值一次一次讀取,直到讀完為止,就像一個(gè)打開的水龍頭,水不斷的流出,直到流干,需要通過監(jiān)聽 data 事件觸發(fā)。
假如現(xiàn)在 1.txt 文件中的內(nèi)容為 0~9 十個(gè)數(shù)字,我們現(xiàn)在創(chuàng)建可讀流并用流動狀態(tài)讀取。
let fs = require("fs");let rs = fs.createReadStream("1.txt", { start: 0, end: 3, highWaterMark: 2});// 讀取文件rs.on("data", data => { console.log(data);});// 監(jiān)聽讀取結(jié)束rs.on("end", () => { console.log("讀完了");});// <Buffer 30 31>// <Buffer 32 33>// 讀完了在上面代碼中,返回的 rs 對象監(jiān)聽了兩個(gè)事件:
data:每次讀取 highWaterMark 個(gè)字節(jié),觸發(fā)一次 data 事件,直到讀取完成,回調(diào)的參數(shù)為每次讀取的 Buffer;
end:當(dāng)讀取完成時(shí)觸發(fā)并執(zhí)行回調(diào)函數(shù)。
我們希望最后讀到的結(jié)果是完整的,所以我們需要把每一次讀到的結(jié)果在 data 事件觸發(fā)時(shí)進(jìn)行拼接,以前我們可能使用下面這種方式。
let fs = require("fs");let rs = fs.createReadStream("1.txt", { start: 0, end: 3, highWaterMark: 2});let str = "";rs.on("data", data => { str += data;});rs.on("end", () => { console.log(str);});// 0123在上面代碼中如果讀取的文件內(nèi)容是中文,每次讀取的 highWaterMark 為兩個(gè)字節(jié),不能組成一個(gè)完整的漢字,在每次讀取時(shí)進(jìn)行 += 操作會默認(rèn)調(diào)用 toString 方法,這樣會導(dǎo)致最后讀取的結(jié)果是亂碼。
新聞熱點(diǎn)
疑難解答
圖片精選