本文摘錄自《Nodejs學習筆記》,更多章節及更新,請訪問 github主頁地址。歡迎加羣交流,羣號 197339705。html
nodejs的核心模塊,基本上都是stream的的實例,好比process.stdout、http.clientRequest。node
對於大部分的nodejs開發者來講,日常並不會直接用到stream模塊,只須要了解stream的運行機制便可(很是重要)。git
而對於想要實現自定義stream實例的開發者來講,就得好好研究stream的擴展API了,好比gulp的內部實現就大量用到了自定義的stream類型。github
來個簡單的例子鎮樓,幾行代碼就實現了讀取文件內容,並打印到控制檯:gulp
const fs = require('fs'); fs.createReadStream('./sample.txt').pipe(process.stdout);
在nodejs中,有四種stream類型:api
Readable:用來讀取數據,好比 fs.createReadStream()
。ide
Writable:用來寫數據,好比 fs.createWriteStream()
。學習
Duplex:可讀+可寫,好比 net.Socket()
。ui
Transform:在讀寫的過程當中,能夠對數據進行修改,好比 zlib.createDeflate()
(數據壓縮/解壓)。code
如下都是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('文件讀取完成,文件內容是['); // 文件讀取完成,文件內容是[你好,我是程序猿小卡]
一樣以寫文件爲例子,好比想將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應該就是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是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);