Node 流 Stream 三二事 1 0 1版本

2021-09-11 13:43:24 字數 4515 閱讀 1974

2018-04-08 星期日 農曆二月廿三 戊戌年 【狗年】 丙辰月 庚午日 宜 祭祀 塑繪 開光 納采 嫁娶 忌 祈福 入宅 造屋 動土 破土

流是基於事件的api,用於管理和處理資料,而且有不錯的效率. 借助事件和非阻塞i/o庫,流模組允許在其可用的時候動態處理,在其不需要的時候釋放掉.

流是一組有序的,有起點和終點的位元組資料傳輸手段。

它不關心檔案的整體內容,只關注是否從檔案中讀到了資料,以及讀到資料之後的處理。

流是乙個抽象介面,被 node 中的很多物件所實現。比如http 伺服器request和response物件都是流。

那麼說了這些,到底有哪些我們常用的流呢?下面我就一一介紹:

我們首先看的是可讀流,它的實現機制是在預設情況下不會將內容輸出,而是在內部先建立乙個buffer,先讀取highwatermark長度。可讀流有5個事件,分別是`data`,`close`,`open`,`end`,`error`,可讀流會瘋狂的觸發data事件,直到讀完為止,除此之外,createreadstream還有兩個事件,暫停(pause)和繼續(resume),讓我們來看一下用法:

複製**

let fs = require('fs');

let path = require('path');

let re = fs.createreadstream(path.join(__dirname,'1.txt'),)

re.on('open',function())

re.on('close',function())

//這裡採用發布訂閱模式,內部有乙個newlisenter函式來監聽例項上綁了哪些事件。而內部的事件觸發採用的是emit()

re.on('error',function(err))

re.on('data',function(data))

setinterval(function(),3000)

re.on('end',function())

複製**

通過這幾個方法一實驗就知道內部是怎麼實現的了,我這裡用vscode跑了一下:

複製**

可寫流相對來說用法就比較簡單了,只有write,end,兩個方法。需要注意的是寫入的資料必須是字串或者buffer。我們來看一下它的用法:

let fs = require('fs');

let ws = fs.createwritestream('./1.txt',);

// 寫入的資料必須是字串或者buffer

// flag代表是否能繼續寫

// 表示符表示的並不是是否寫入 表示的是能否繼續寫,但是返回false 也不會丟失,就是會把內容放到記憶體中

let flag = ws.write(1+'','utf8',()=>{}); // 非同步的方法

console.log(flag);

flag = ws.write(1+'','utf8',()=>{}); // 非同步的方法

console.log(flag);

// flag = ws.write(1+'','utf8',()=>{}); // 非同步的方法

// console.log(flag);

'ok'); // 當寫完後 就不能再繼續寫了

'123'); //write after end

複製**

ws還有乙個方法就是drain,抽乾方法 當都寫入完後會觸發drain事件, 必須快取區滿了 ,滿了後被清空了才會出發drain

let flag = ws.write(1+'','utf8',()=>{}); // 非同步的方法

console.log(flag);

flag = ws.write(1+'','utf8',()=>{}); // 非同步的方法

console.log(flag);

flag = ws.write(1+'','utf8',()=>{}); // 非同步的方法

console.log(flag);

ws.on('drain',function

());

複製**

這個drain以後可以讓可寫流配合可讀流寫乙個pipe方法。pipe是什麼呢? 其實就是乙個讀一點寫一點的方法,實現的是下面的這樣的事:

let fs = require('fs');

let path = require('path');

let rs = fs.createreadstream(path.join(__dirname,'./1.txt'),)

let ws = fs.createwritestream(path.join(__dirname,'./2.txt'),)

rs.on('data',function(chunk)

})ws.on('drain',function

())複製**

而pipe 的實現方法就簡單的讓人感動:

rs.pipe(ws); 

複製**

readable也是乙個很實用的可讀流的方法,它可以很智慧型的的實現暫停流。 readable的實現原理是:

當我只要建立乙個流 就會先把快取區 填滿,等待著你自己消費 如果當前快取區被清空後會再次觸發readable事件 當你消費小於 最高水位線時 會自動新增highwater這麼多資料

let fs = require('fs');

let path = require('path');

let rs = fs.createreadstream(path.join(__dirname,'1.txt'),);

// rs.on('data'); 正常情況下我們會直接用data,但是這個方法會一直讀

rs.on('readable',function

());

複製**

執行結果是

這個readable還有乙個特別智慧型的操作,當讀乙個或沒讀到highwatermark的值時,並且半天沒操作,程式會自動給你『續杯『。

let fs = require('fs');

let path = require('path');

let rs = fs.createreadstream(path.join(__dirname,'1.txt'),);

rs.on('readable',function

(),1000)

});複製**

結果如下

我想讀5個 快取區只有3個 他會更改快取區的大小再去讀取

雙工流,讀的時候要以this.push(null)結尾,寫的時候要以 callback();結尾。

let  =  require('stream');

// 雙工流 又能讀 又能寫,而且讀取可以沒關係(互不干擾);

let d = duplex(,

write(chunk,encoding,callback)

});d.on('data',function(data));

d.write('hello');

複製**

轉換流,就是duplex 他不需要實現read write。

let  =  require('stream');

// 他的引數和可寫流一樣

let tranform1 = transform(

});let tranform2 = transform(

});// 等待你的輸入

// rs.pipe(ws);

// 希望將輸入的內容轉化成大寫在輸出出來

process.stdin.pipe(tranform1).pipe(tranform2);

複製**

這個寫法是為了讓輸入轉化成大寫輸出,process.stdin(標準輸入)可視為可讀流。 最後用node 執行一下這個檔案,輸入小寫字母就會轉化成大寫字母。

可讀流裡只能放buffer或者字串 物件流裡可以放物件

let  = require('stream');

// 想實現什麼流 就繼承這個流

// readable裡面有乙個read()方法,預設掉_read()

// readable中提供了乙個push方法你呼叫push方法就會觸發data事件

let index = 9;

class myread extends readable

}let mr = new myread;

mr.on('data',function(data));

複製**

node中的stream(流)內建模組

stream是node.js提供的又乙個僅在服務區端可用的模組,目的是支援 流 這種資料結構。什麼是流?流是一種抽象的資料結構。想象水流,當在水管中流動時,就可以從某個地方 例如自來水廠 源源不斷地到達另乙個地方 比如你家的洗手池 我們也可以把資料看成是資料流,比如你敲鍵盤的時候,就可以把每個字元依...

Node常用內建模組 stream

檔案流讀取文字內容 use strict var fs require fs var rs fs.createreadstream sample.txt utf 8 rs.on data function chunk rs.on end function chunk rs.on error func...

Stream流 方法引用

流式思想 類似於 生產流水線 模型就是每乙個位置 延遲方法 返回型別是stream介面自身型別的方法,可以鏈式程式設計 包括filter,map,skip等 終結方法 返回型別不再是stream介面自身型別的方法,包括count,foreach stream流常用方法 void foreach co...