流能夠是可讀的、可寫的、或者是可讀寫的。全部的流都是EventEmitter的實例。javascript
全部使用Node.js API建立的流對象都只能操做strings和Buffer(或Unit8Array)。可是一些第三方流的實現,可以操做其餘類型的javascript值(除了null,它在流處理中有特殊意義),這種類型的流被認爲是工做在‘對象模式’java
Writable和Readable流都會將數據存儲到內部的緩存(buffer)中緩存
例如fs.createReadStream()
函數
可讀流(Readable streams)是對提供數據的源頭(source)的抽象ui
兩種工做模式:flowing(流動模式)和paused(暫停模式)code
初始工做模式都是paused的Readable流,能夠經過三種途徑切換到flowing模式。orm
可讀流能夠經過兩種方式切換到paused對象
close
事件:在流或其底層資源(好比一個文件)關閉後觸發。事件觸發後,該流將不會再觸發任何事件。接口
data
事件:在流將數據傳遞給消費者時觸發。當流轉換到flowing模式時會觸發該事件。處理器的參數是Buffer對象,若是你調用了Readable的setEncoding(encoding)方法,處理器的參數就是String對象。隊列
end
事件:在流中再沒有數據可供消費時觸發。
const readable = readableStreamSomehow() readable.on('data', (chunk) => { console.log(`received ${chunk.length} bytes of buffer data.`) }) readable.on('end', () => { console.log('no more data.') })
error
事件:一般底層系統內部出錯從而不能產生數據,或當流的實現試圖傳遞錯誤數據時發生。回調函數將接收到一個Error對象。
readable
事件:將在流中有數據可供讀取時觸發。stream.read()返回可用的數據。
const readable = readableStreamSomehow() readable.on('readable', () => { // 有一些數據可讀 })
在到達流數據尾部時,該事件也會觸發。觸發順序在end事件以前。stream.read()返回null
// foo.txt是一個空文件 const fs = require('fs') const rr = fs.createReadStream('foo.txt') rr.on('readable', () => { console.log('readable', rr.read) // null }) rr.on('end', () => { console.log('end') // end })
readable.pipe(destination[,options])
:綁定一個writable到readable上,造成一個管道,並將全部數據傳給綁定的writable。能夠在單個可讀流上綁定多個可寫流。
const r = fs.createReadStream('file.txt') const z = zlib.createGzip() const w = fs.createWriteStream('file.txt.gz') r.pipe(z).pipe(w)
默認狀況下,當源可讀流觸發end事件時,目標流也會調用stream.end()方法從而結束寫入。要禁止這一默認行爲,end選項應該指定爲false。
reader.pipe(writer, {end: false}) reader.on('end', () => { writer.end('goodbye) })
若是可讀流在處理時發生錯誤,目標可寫流不會自動關閉。 若是發生錯誤,須要手動關閉全部流以免內存泄漏。
通常來講,建議開發人員避免使用'readable'事件和readable.read()方法,使用readable.pipe()或'data'事件代替。
writable.unpipe([destination])
:readable.unpipe()方法將以前經過stream.pipe()方法綁定的流分離
若是 destination 沒有傳入, 則全部綁定的流都會被分離.
若是傳入 destination, 但它沒有被pipe()綁定過,則該方法不做爲.
例如fs.createWriteStream()
Writable streams是destination的一種抽象,這種destination容許數據寫入
close
事件:在流或者底層資源(好比一個文件)關閉後觸發,事件觸發後該流將不會再觸發任何事件。
drain
事件`:若是調用stream.write(chunk)方法返回false,流將在適當的時機觸發drain事件,這時才能夠繼續向流中寫入數據。
error
事件`:在寫入數據出錯或者使用管道(pipe)出錯時觸發,事件發生時,回調函數僅會接收到一個Error參數。注意:error事件發生時,流並不會關閉。
finish事件
:在調用了stream.end()方法,且緩衝區數據都已經傳給底層系統以後,finish事件將被觸發。
pipe事件
:在可讀流上調用stream.pipe()方法,並在目標流向中添加當前可寫流時,將會在可寫流上觸發pipe事件。
const writer = writeStreamSomehow() const reader = readStreamSomehow() writer.on('pipe', (src) => { console.log('piping into the writer') assert.equal(src, reader) }) reader.pipe(writer)
writable.end([chunk][,encoding][,callback])
:調用writable.end()方法代表接下來沒有數據要被寫入writable,經過傳入可選的chunk和encoding參數,能夠在關閉流以前再寫入一段數據。若是傳入了可選的callback函數,將做爲finish事件的回掉函數。
在調用了stream.end()方法以後,再調用stream.write()方法會致使錯誤。
// 寫入hello 並用world結束寫入 const file = fs.createWriteStream('example.txt) file.write('hello, ') file.end('wrold!) // 後面不容許再寫入數據
writable.write(chunk[,encoding][,callback])
:向流中寫入數據,並在數據處理完成後調用callback。咱們建議,一旦write()返回false,在'drain'事件觸發前,不能寫入任何數據塊。
writable.uncork()
例如net.Socket()
例如zlib.createDeflate()