模塊概覽
nodejs的核心模塊,基本上都是stream的的實例,比如process.stdout、http.clientRequest。
對于大部分的nodejs開發者來說,平常并不會直接用到stream模塊,只需要了解stream的運行機制即可(非常重要)。
而對于想要實現自定義stream實例的開發者來說,就得好好研究stream的擴展API了,比如gulp的內部實現就大量用到了自定義的stream類型。
來個簡單的例子鎮樓,幾行代碼就實現了讀取文件內容,并打印到控制臺:
constfs =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
其他
例子一:
varfs =require('fs');
fs.readFile('./sample.txt','utf8',function(err, content){// 文件讀取完成,文件內容是 [你好,我是程序猿小卡]console.log('文件讀取完成,文件內容是 [%s]', content);});
例子三:
這里使用了.pipe(dest),好處在于,如果文件
varfs =require('fs');fs.createReadStream('./sample.txt').pipe(process.stdout);
注意:這里只是原封不動的將內容輸出到控制臺,所以實際上跟前兩個例子有細微差異。可以稍做修改,達到上面同樣的效果
varfs =require('fs');varonEnd =function(){ process.stdout.write(']'); };varfileStream = fs.createReadStream('./sample.txt');fileStream.on('end', onEnd)fileStream.pipe(process.stdout);process.stdout.write('文件讀取完成,文件內容是[');// 文件讀取完成,文件內容是[你好,我是程序猿小卡]
Writable Stream
同樣以寫文件為例子,比如想將hello world寫到sample.txt里。
例子一:
varfs =require('fs');varcontent ='hello world';varfilepath ='./sample.txt';fs.writeFile(filepath, content);
例子二:
varfs =require('fs');varcontent ='hello world';varfilepath ='./sample.txt';varwriteStram = fs.createWriteStream(filepath);writeStram.write(content);writeStram.end();
Duplex Stream
最常見的Duplex stream應該就是net.Socket實例了,在前面的文章里有接觸過,這里就直接上代碼了,這里包含服務端代碼、客戶端代碼。
服務端代碼:
varnet =require('net');varopt = {host:'127.0.0.1',port:'3000'};varclient = 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();});
客戶端代碼:
varnet =require('net');varopt = {host:'127.0.0.1',port:'3000'};varclient = 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壓縮。
varfs =require('fs');varzlib =require('zlib');vargzip = zlib.createGzip();varinFile = fs.createReadStream('./extra/fileForCompress.txt');varout = fs.createWriteStream('./extra/fileForCompress.txt.gz');inFile.pipe(gzip).pipe(out);