大家好,今天我會來說明stream和buffer的概念。
各位可以先設想一下,當我們希望從一段距離外的水塔,取水到自家的飲水機,第一個方法可以選擇用一個非常大的水箱,來把家裡所需用的水一次通通裝滿再帶回家,或是第二種方法,用容量小一點的水瓶,裝滿了就帶回家再分成好幾趟來回。
能看到這兩種方法,若不考慮來回的成本,第一種方式在裝水的過程中,家裡都沒辦法使用任何的水資源;而第二種方法則可以先裝一部分的水給家裡使用,再慢慢的裝滿所有的水。
在程式的資料輸入和輸出時,大部分都會採用上面所說的第二種方法,因為很多檔案中的資料是成千上萬的,程式若一直等到資料讀取完,肯定會浪費不少時間。所以,stream的概念就是會將檔案中的data分成好幾塊部分,當讀取到一部分的資料後便將其放置到buffer,buffer也就像是上面所說的水瓶,送到我們的程式作使用。這樣一來就能節省非常多時間。
說了那麼多,直接來看範例吧!
上圖是我要讀取的txt檔,可以看到有30000多行的文字。
使用stream的方式讀取檔案code如下:
const fs = require('fs');
//readStream為我宣告的變數
//{ encoding : 'utf-8' }代表將資料用utf-8的方式讀取,讓文字正常輸出
const readStream = fs.createReadStream('./LotsOfText.txt', { encoding : 'utf-8' });
//buff為我宣告的變數,代表讀取到的那一部分資料
//.on代表readStream會一直讀取,直到檔案已被讀取完畢。
readStream.on('data', (buff) => {
//每讀取到新的data,就會印出此訊息
console.log("=======讀取到了新的buffer=======");
console.log(buff);
});
這樣就能使用stream的方式讀檔囉!下圖為輸出結果讀取到新的buffer時所印出的訊息:
那當我們要輸出(write)檔案時,也同樣可以用stream的方式。
假設我們想要將讀取的txt檔再寫入到新的txt檔,code如下:
const fs = require('fs');
const readStream = fs.createReadStream('./LotsOfText.txt', { encoding : 'utf-8' });
const writeStream = fs.createWriteStream('./output.txt');
readStream.on('data', (buff) => {
console.log("=======讀取到了新的buffer=======");
console.log(buff);
writeStream.write("\n=======輸出新的資料=======\n");
writeStream.write(buff);
});
再看看輸出到output.txt的結果:
同樣能看到在輸入新的資料時會印出訊息。
介紹完上述的read和write stream後,這邊再介紹一個將兩個功能結合在一起的功能,叫做pipe。
pipe的功能為用stream的方式讀取檔案,並同樣將結果輸出到另一個檔案。所以我們可以將上面的code簡化成下方的樣子~
const fs = require('fs');
const readStream = fs.createReadStream('./LotsOfText.txt', { encoding : 'utf-8' });
const writeStream = fs.createWriteStream('./output.txt');
readStream.pipe(writeStream);
這樣的結果除了印出給使用者看的訊息以外,其他都一樣!所以這一定也是一個非常實用的方法~
以上為今天的學習,明天見~