談談node中流的理解

node中Stream分為Readable(可讀流)、Writable(可寫流)、Duplex(可讀寫流)、Transform(讀寫過程中可以修改和變換數據的 Duplex 流)。

為了實現可寫流,我們需要使用流模塊中的Writable構造函數。 我們只需給Writable構造函數傳遞一些選項并創建一個對象。唯一需要的選項是write函數,該函數揭露數據塊要往哪里寫。

chunk通常是一個buffer,除非我們配置不同的流。

encoding是在特定情況下需要的參數,通常我們可以忽略它。

callback是在完成處理數據塊后需要調用的函數。這是寫數據成功與否的標志。若要發出故障信號,請用錯誤對象調用回調函數

下面代碼用ES6對可寫流進行代碼簡要的實現:

let fs = require('fs');

let EventEmitter = require('events');

class WriteStream extends EventEmitter {

constructor(path, options) {

super();

let self = this;

Object.assign(self, options); //還需設置默認值

self.path = path; //文件路經

self.isWriting = false;

self.Buffer = []; //緩沖區

self.len = null;

self.pos = self.start; //初始化寫入位置

self.fd = null;

self.open();

}

open() {//首先打開文件

let self = this;

fs.open(self.path, self.flags, self.mode, (err, fd) => {

self.fd = fd;

if (err) return self.destroy(err);

self.emit('open');

});

}

destroy(err) {

fs.close(this.fd, () => {

this.emit('error', err);

});

}

write(chunk, encoding, cb) {

let self = this

, ret = null;

encoding = encoding?encoding:self.encoding; //優先使用write傳入的編碼方式

chunk = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, encoding);

self.len += chunk.length;

ret = self.highWaterMark > self.len; //判斷當前最新的緩沖區是否已達到最高水位線

if (self.isWriting) { //說明正在調用底層方法真正寫入文件,先寫入Buffer

self.Buffer.push({

chunk

, cb

});

} else {

self.isWriting = true;

self._write(chunk, cb, () => self.clearBuffer());

}

return ret;

}

_write(chunk, cb, clear) {

let self = this;

if (!self.fd) return self.once('open', () => {

self._write(chunk, cb, clear)

});

fs.write(self.fd, chunk, 0, chunk.length, self.pos, (err, bytesWritten) => {

if (err) {

if (self.autoClose) {

self.destroy();

self.emit('error', err);

}

}

self.len -= bytesWritten;

self.pos += bytesWritten;

cb && cb();

clear && clear();

});

}

clearBuffer() {

let self = this

, data = null;

data = self.Buffer.shift();

if (data) {

self._write(data.chunk, data.cb, () => self.clearBuffer());

} else { //此時說明緩沖區已無數據

self.isWriting = false;

self.emit('drain');

}

}

}

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,825評論 6 546
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,814評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,980評論 0 384
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 64,064評論 1 319
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,779評論 6 414
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,109評論 1 330
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,099評論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,287評論 0 291
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,799評論 1 338
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,515評論 3 361
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,750評論 1 375
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,221評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,933評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,327評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,667評論 1 296
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,492評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,703評論 2 380

推薦閱讀更多精彩內容