Node.js數(shù)據(jù)流Stream之Readable流和Writable流用法
一、前傳
Stream在很多語(yǔ)言都會(huì)有,當(dāng)然Node.js也不例外。數(shù)據(jù)流是可讀、可寫(xiě)、或即可讀又可寫(xiě)的內(nèi)存結(jié)構(gòu)。Node.js中主要包括Readable、Writable、Duplex(雙工)和Transform(變換)流。但是在學(xué)這些之前先學(xué)會(huì)util模塊中的一個(gè)從其他對(duì)象繼承的功能.
util模塊提供了util.inherits()方法來(lái)允許你創(chuàng)建一個(gè)繼承另一個(gè)對(duì)象的prototype(原形)方法的對(duì)象。當(dāng)創(chuàng)建一個(gè)新對(duì)象時(shí),prototype方法自動(dòng)被使用。
util.inherits(constructor,superconstructor)原形constructor被設(shè)定為原形superConstructor,并在一個(gè)新的對(duì)象被創(chuàng)建時(shí)執(zhí)行??梢酝ㄟ^(guò)使用constructor.super_屬性從自定義對(duì)象的構(gòu)造函數(shù)訪問(wèn)supercontructor.
二、Readable流
有的前傳util模塊從其他對(duì)象繼承的功能的了解,Readable就很好理解了.主要它包含以下方法和事件。
1.事件:
readable:在數(shù)據(jù)塊可以從流中讀取的時(shí)候發(fā)出。
data:類(lèi)似readable,不同之處在于,當(dāng)數(shù)據(jù)的事件處理程序被連接時(shí),流被轉(zhuǎn)變成流動(dòng)的模式,并且數(shù)據(jù)處理程序被連續(xù)的調(diào)用,直到所有數(shù)據(jù)都被用盡
end:當(dāng)數(shù)據(jù)不再被提供時(shí)由流發(fā)出
close:當(dāng)?shù)讓淤Y源,如文件,已關(guān)閉時(shí)發(fā)出。
error:在接收數(shù)據(jù)中出錯(cuò)是發(fā)出。
2.方法:
read([size]):從流中讀數(shù)據(jù).數(shù)據(jù)可以是String、Buffer、null(下面代碼會(huì)有),當(dāng)指定size,那么只讀僅限于那個(gè)字節(jié)數(shù)
setEncoding(encoding):設(shè)置read()請(qǐng)求讀取返回String時(shí)使用的編碼
pause():暫停從該對(duì)象發(fā)出的data事件
resume():恢復(fù)從該對(duì)象發(fā)出的data事件
pipe(destination,[options]):把這個(gè)流的輸出傳輸?shù)揭粋€(gè)由deatination(目的地)指定的Writable流對(duì)象。options是一個(gè)js對(duì)象.例如:{end:true}當(dāng)Readable結(jié)束時(shí)就結(jié)束Writable目的地。
unpipe([destination]):從Writale目的地?cái)嚅_(kāi)這一對(duì)象。
3.demo:
var stream = require('stream');
var util = require('util');
util.inherits(Answers, stream.Readable);
function Answers(opt) {
stream.Readable.call(this, opt);
this.quotes = ["yes", "no", "maybe"];
this._index = 0;
}
Answers.prototype._read = function() {
if (this._index > this.quotes.length){
this.push(null);
} else {
this.push(this.quotes[this._index]);
this._index += 1;
}
};
var r = new Answers();
console.log("Direct read: " + r.read().toString());
r.on('data', function(data){
console.log("Callback read: " + data.toString());
});
r.on('end', function(data){
console.log("No more answers.");
});
r.on('readable',function(data)
{
console.log('readable');
});輸出結(jié)果:
"C:\Program Files (x86)\JetBrains\WebStorm 11.0.3\bin\runnerw.exe" F:\nodejs\node.exe stream_read.js
Direct read: yes
readable
Callback read: no
Callback read: maybe
readable
readable
readable
No more answers.Process finished with exit code 0
上面定義了一個(gè)通過(guò)util.inherits()繼承Readable流的對(duì)象,從輸出結(jié)果可以看到輸出了3個(gè)字符串,但readable事件確執(zhí)行了4次,其實(shí)前面也有寫(xiě),read()可以是null,最后是push(null)了。
三、Writable流
有讀就會(huì)有寫(xiě),畢竟是可逆的,它和readable一樣也有一些事件和方法
1.方法
write(chunk,[encoding],[callback]):將數(shù)據(jù)寫(xiě)入流。chunk(數(shù)據(jù)塊)中包含要寫(xiě)入的數(shù)據(jù),encoding指定字符串的編碼,callback指定當(dāng)數(shù)據(jù)已經(jīng)完全刷新時(shí)執(zhí)行的一個(gè)回調(diào)函數(shù)。如果成功寫(xiě)入,write()返回true.
end([chunk],[encoding],[callback]):與write()相同,它把Writable對(duì)象設(shè)為不再接受數(shù)據(jù)的狀態(tài),并發(fā)送finish事件。
2.事件
drain:在write()調(diào)用返回false后,當(dāng)準(zhǔn)備好開(kāi)始寫(xiě)更多數(shù)據(jù)時(shí),發(fā)出此事件通知監(jiān)視器。
finish:當(dāng)end()在Writable對(duì)象上調(diào)用,所以數(shù)據(jù)被刷新,并不會(huì)有更多的數(shù)據(jù)被接受時(shí)觸發(fā)
pipe:當(dāng)pipe()方法在Readable流上調(diào)用,已添加此writable為目的地時(shí)發(fā)出
unpipe:當(dāng)unpipe()方法被調(diào)用,以刪除Writable為目的地時(shí)發(fā)出。
3.demo
var stream = require('stream');
var util = require('util');
util.inherits(Writer, stream.Writable);
function Writer(opt) {
stream.Writable.call(this, opt);
this.data = new Array();
}
Writer.prototype._write = function(data, encoding, callback) {
this.data.push(data.toString('utf8'));
console.log("Adding: " + data);
callback();
};
var w = new Writer();
for (var i=1; i<=5; i++){
w.write("Item" + i, 'utf8');
}
w.end("ItemLast");
console.log(w.data);輸出結(jié)果:
"C:\Program Files (x86)\JetBrains\WebStorm 11.0.3\bin\runnerw.exe" F:\nodejs\node.exe stream_write.js
Adding: Item1
Adding: Item2
Adding: Item3
Adding: Item4
Adding: Item5
Adding: ItemLast
[ 'Item1', 'Item2', 'Item3', 'Item4', 'Item5', 'ItemLast' ]Process finished with exit code 0
四、把Readable流用管道輸送到Writable流
上面也介紹了Readable流pipe()方法,這個(gè)主要是來(lái)測(cè)試
var stream = require('stream');
var util = require('util');
util.inherits(Reader, stream.Readable);
util.inherits(Writer, stream.Writable);
function Reader(opt) {
stream.Readable.call(this, opt);
this._index = 1;
}
Reader.prototype._read = function(size) {
var i = this._index++;
if (i > 10){
this.push(null);
} else {
this.push("Item " + i.toString());
}
};
function Writer(opt) {
stream.Writable.call(this, opt);
this._index = 1;
}
Writer.prototype._write = function(data, encoding, callback) {
console.log(data.toString());
callback();
};
var r = new Reader();
var w = new Writer();
w.on('pipe',function(){
console.log('pipe');
});
r.pipe(w);輸出結(jié)果:
"C:\Program Files (x86)\JetBrains\WebStorm 11.0.3\bin\runnerw.exe" F:\nodejs\node.exe stream_piped.js
pipe
Item 1
Item 2
Item 3
Item 4
Item 5
Item 6
Item 7
Item 8
Item 9
Item 10Process finished with exit code 0
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Node.js中的流(Stream)的作用詳解
- node.js同步/異步文件讀寫(xiě)-fs,Stream文件流操作實(shí)例詳解
- Node.js數(shù)據(jù)流Stream之Duplex流和Transform流用法
- node.js中stream流中可讀流和可寫(xiě)流的實(shí)現(xiàn)與使用方法實(shí)例分析
- node.js使用stream模塊實(shí)現(xiàn)自定義流示例
- Node.js中你不可不精的Stream(流)
- Node.js中流(stream)的使用方法示例
- Node.js中的流(Stream)介紹
- Node.js 中的流Stream模塊簡(jiǎn)介及如何使用流進(jìn)行數(shù)據(jù)處理
相關(guān)文章
NodeJS前端自動(dòng)化部署實(shí)現(xiàn)實(shí)例詳解
這篇文章主要為大家介紹了NodeJS前端自動(dòng)化部署實(shí)現(xiàn)實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-10-10
淺談Node Inspector 代理實(shí)現(xiàn)
這篇文章主要介紹了淺談Node Inspector 代理實(shí)現(xiàn),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-10-10
如何使用 Node.js 實(shí)現(xiàn)一個(gè)上傳圖片接口
本文介紹了如何使用Node.js和Express框架創(chuàng)建一個(gè)簡(jiǎn)單的上傳圖片接口,首先,通過(guò)npm初始化項(xiàng)目并安裝必要的依賴(lài),如express和multer,然后,在index.js文件中編寫(xiě)上傳圖片的邏輯,并通過(guò)Postman測(cè)試接口,感興趣的朋友跟隨小編一起看看吧2025-02-02
node前端開(kāi)發(fā)模板引擎Jade的入門(mén)
這篇文章主要介紹了node前端開(kāi)發(fā)模板引擎Jade的入門(mén),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-05-05
nodejs將JSON字符串轉(zhuǎn)化為JSON對(duì)象報(bào)錯(cuò)的解決
這篇文章主要介紹了nodejs將JSON字符串轉(zhuǎn)化為JSON對(duì)象報(bào)錯(cuò)的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07
Node.js命令行/批處理中如何更改Linux用戶(hù)密碼淺析
這篇文章主要給大家介紹了關(guān)于Node.js命令行/批處理中如何更改Linux用戶(hù)密碼的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-07-07

