文章出處

本文摘錄自《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包括zlibcrypto,這里舉個簡單例子:文件的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);

相關鏈接

https://nodejs.org/api/stream.html


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()