Node.js | Stream(流)
簡介
Stream
是一個抽象接口,Node
中有很多對象實現了這個接口。
例如:對http
伺服器發起請求的request
對象就是一個Stream
,還有stdout
(標準輸出)。
Node.js Stream
有四種流類型:
Readable
:可讀操作。
Writable
:可寫操作。
Duplex
:可讀可寫操作.
Transform
:操作被寫入資料,然後讀出結果。
所有的Stream
對像都是EventEmitter
的實例。
常用的事件有:
data
:當有資料可讀時觸發。
end
:沒有更多的資料可讀時觸發。
error
:在接收和寫入過程中發生錯誤時觸發。
finish
:所有資料已被寫入到底層系統時觸發。
註:詳細Doc Link
讀取
input.txt
文件,內容如下:
1
| J.J.'s Blogs 技術筆記 http://localhost:4000/
|
main.js
,程式如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| var fs = require("fs"); var data = '';
var readerStream = fs.createReadStream('input.txt');
readerStream.setEncoding('UTF8');
readerStream.on('data', function(chunk) { data += chunk; });
readerStream.on('end',function(){ console.log(data); });
readerStream.on('error', function(err){ console.log(err.stack); });
console.log("執行完畢");
|
執行結果如下:
1 2 3
| $ node main.js 執行完畢 J.J.'s Blogs 技術筆記 http://localhost:4000/
|
寫入
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| var fs = require("fs"); var data = "J.J.'s Blogs 技術筆記 http://localhost:4000/";
var writerStream = fs.createWriteStream('output.txt');
writerStream.write(data,'UTF8');
writerStream.end();
writerStream.on('finish', function() { console.log("寫入完成。"); });
writerStream.on('error', function(err){ console.log(err.stack); });
console.log("執行完畢。");
|
執行結果如下:
1 2 3
| $ $ node main.js 執行完畢。 寫入完成。
|
查看output.txt
內容:
1 2
| $ cat output.txt J.J.'s Blogs 技術筆記 http://localhost:4000/%
|
管道
管道提供了一個輸出流到輸入流的機制。通常我們用於從一個流中獲取資料並將資料傳遞到另外一個流中。
如上面的圖片所示,我們把文件比作裝水的桶,而水就是文件裡的內容,我們用一根管子(pipe
)連接兩個桶使得水從一個桶流入另一個桶,這樣就慢慢的實現了大文件的複製過程。
以下實例我們通過讀取一個文件內容並將內容寫入到另外一個文件中。
input.txt
文件內容如下:
1 2
| J.J.'s Blogs 技術筆記 http://localhost:4000/ 管道流操作實例
|
main.js
,程式如下:
1 2 3 4 5 6 7 8 9 10 11 12 13
| var fs = require("fs");
var readerStream = fs.createReadStream('input.txt');
var writerStream = fs.createWriteStream('output.txt');
readerStream.pipe(writerStream);
console.log("執行完畢");
|
程式執行結果如下:
查看output.txt
文件的內容:
1 2 3
| $ cat output.txt J.J.'s Blogs 技術筆記 http://localhost:4000/ 管道流操作實例%
|
鍊式流
鍊式是通過連接輸出流到另外一個流並建立多個流操作鏈的機制。鍊式流一般用於管道操作。
接下來我們就是用管道和鍊式來壓縮和解壓文件。
壓縮
compress.js
,程式如下:
1 2 3 4 5 6 7 8 9
| var fs = require("fs"); var zlib = require('zlib');
fs.createReadStream('input.txt') .pipe(zlib.createGzip()) .pipe(fs.createWriteStream('input.txt.gz')); console.log("文件壓縮完成。");
|
執行結果如下:
1 2
| $ node compress.js 文件壓縮完成。
|
執行完以上操作後,我們可以看到當前目錄下生成了input.txt
的壓縮文件input.txt.gz
。
解壓該
decompress.js
,程式如下:
1 2 3 4 5 6 7 8 9
| var fs = require("fs"); var zlib = require('zlib');
fs.createReadStream('input.txt.gz') .pipe(zlib.createGunzip()) .pipe(fs.createWriteStream('input.txt')); console.log("文件解壓完成。");
|
執行結果如下:
1 2
| $ node decompress.js 文件解壓完成。
|
註:以上參考了
Node.js Stream(流)