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...