本文摘錄自《Nodejs學習筆記》,更多章節及更新,請訪問 github主頁地址。歡迎加群交流,群號 197339705。
模塊概覽
nodejs的核心模塊,基本上都是stream的的實例,比如process.stdout、http.clientRequest。
對于大部分的nodejs開發者來說,平常并不會直接用到stream模塊,只需要了解stream的運行機制即可(非常重要)。
而對于想要實現自定義stream實例的開發者來說,就得好好研究stream的擴展API了,比如gulp的內部實現就大量用到了自定義的stream類型。
來個簡單的例子鎮樓,幾行代碼就實現了讀取文件內容,并打印到控制臺:
const fs = require('fs');
fs.createReadStream('./sample.txt').pipe(process.stdout);
Stream分類
在nodejs中,有四種stream類型:
- Readable:用來讀取數據,比如
fs.createReadStream()
。 - Writable:用來寫數據,比如
fs.createWriteStream()
。 - Duplex:可讀+可寫,比如
net.Socket()
。 - Transform:在讀寫的過程中,可以對數據進行修改,比如
zlib.createDeflate()
(數據壓縮/解壓)。
Readable Stream
以下都是nodejs中常見的Readable Stream,當然還有其他的,可自行查看文檔。
- http.IncomingRequest
- fs.createReadStream()
- process.stdin
- 其他
例子一:
var fs = require('fs');
fs.readFile('./sample.txt', 'utf8', function(err, content){
// 文件讀取完成,文件內容是 [你好,我是程序猿小卡]
console.log('文件讀取完成,文件內容是 [%s]', content);
});
例子二:
var fs = require('fs');
var readStream = fs.createReadStream('./sample.txt');
var content = '';
readStream.setEncoding('utf8');
readStream.on('data', function(chunk){
content += chunk;
});
readStream.on('end', function(chunk){
// 文件讀取完成,文件內容是 [你好,我是程序猿小卡]
console.log('文件讀取完成,文件內容是 [%s]', content);
});
例子三:
這里使用了.pipe(dest)
,好處在于,如果文件
var fs = require('fs');
fs.createReadStream('./sample.txt').pipe(process.stdout);
注意:這里只是原封不動的將內容輸出到控制臺,所以實際上跟前兩個例子有細微差異。可以稍做修改,達到上面同樣的效果
var fs = require('fs');
var onEnd = function(){
process.stdout.write(']');
};
var fileStream = fs.createReadStream('./sample.txt');
fileStream.on('end', onEnd)
fileStream.pipe(process.stdout);
process.stdout.write('文件讀取完成,文件內容是[');
// 文件讀取完成,文件內容是[你好,我是程序猿小卡]
Writable Stream
同樣以寫文件為例子,比如想將hello world
寫到sample.txt
里。
例子一:
var fs = require('fs');
var content = 'hello world';
var filepath = './sample.txt';
fs.writeFile(filepath, content);
例子二:
var fs = require('fs');
var content = 'hello world';
var filepath = './sample.txt';
var writeStram = fs.createWriteStream(filepath);
writeStram.write(content);
writeStram.end();
Duplex Stream
最常見的Duplex stream應該就是net.Socket
實例了,在前面的文章里有接觸過,這里就直接上代碼了,這里包含服務端代碼、客戶端代碼。
服務端代碼:
var net = require('net');
var opt = {
host: '127.0.0.1',
port: '3000'
};
var client = net.connect(opt, function(){
client.write('msg from client'); // 可寫
});
// 可讀
client.on('data', function(data){
// server: msg from client [msg from client]
console.log('client: got reply from server [%s]', data);
client.end();
});
客戶端代碼:
var net = require('net');
var opt = {
host: '127.0.0.1',
port: '3000'
};
var client = net.connect(opt, function(){
client.write('msg from client'); // 可寫
});
// 可讀
client.on('data', function(data){
// lient: got reply from server [reply from server]
console.log('client: got reply from server [%s]', data);
client.end();
});
Transform Stream
Transform stream是Duplex stream的特例,也就是說,Transform stream也同時可讀可寫。跟Duplex stream的區別點在于,Transform stream的輸出與輸入是存在相關性的。
常見的Transform stream包括zlib
、crypto
,這里舉個簡單例子:文件的gzip壓縮。
var fs = require('fs');
var zlib = require('zlib');
var gzip = zlib.createGzip();
var inFile = fs.createReadStream('./extra/fileForCompress.txt');
var out = fs.createWriteStream('./extra/fileForCompress.txt.gz');
inFile.pipe(gzip).pipe(out);
相關鏈接
文章列表