iT邦幫忙

2023 iThome 鐵人賽

DAY 27
0
自我挑戰組

node.js 從初學者到高手!系列 第 27

Day 27 node.js - stream, buffer之概念 & 如何有效率的讀取和寫入檔案

  • 分享至 

  • xImage
  •  

大家好,今天我會來說明stream和buffer的概念。

各位可以先設想一下,當我們希望從一段距離外的水塔,取水到自家的飲水機,第一個方法可以選擇用一個非常大的水箱,來把家裡所需用的水一次通通裝滿再帶回家,或是第二種方法,用容量小一點的水瓶,裝滿了就帶回家再分成好幾趟來回。

能看到這兩種方法,若不考慮來回的成本,第一種方式在裝水的過程中,家裡都沒辦法使用任何的水資源;而第二種方法則可以先裝一部分的水給家裡使用,再慢慢的裝滿所有的水。

在程式的資料輸入和輸出時,大部分都會採用上面所說的第二種方法,因為很多檔案中的資料是成千上萬的,程式若一直等到資料讀取完,肯定會浪費不少時間。所以,stream的概念就是會將檔案中的data分成好幾塊部分,當讀取到一部分的資料後便將其放置到buffer,buffer也就像是上面所說的水瓶,送到我們的程式作使用。這樣一來就能節省非常多時間。

說了那麼多,直接來看範例吧!
https://ithelp.ithome.com.tw/upload/images/20231011/20163170S3nDwuxyla.png
上圖是我要讀取的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時所印出的訊息:
https://ithelp.ithome.com.tw/upload/images/20231011/20163170InxCURDhTp.png

那當我們要輸出(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的結果:
https://ithelp.ithome.com.tw/upload/images/20231011/20163170PdHG8KZ4Gp.png
同樣能看到在輸入新的資料時會印出訊息。

介紹完上述的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);

這樣的結果除了印出給使用者看的訊息以外,其他都一樣!所以這一定也是一個非常實用的方法~

以上為今天的學習,明天見~


上一篇
Day 26 node.js - 使用node.js的FileSystem讀取、編輯檔案
下一篇
Day 28 node.js - 學習server的創立過程 & 語法說明
系列文
node.js 從初學者到高手!30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言