一文聊聊Node中的stream(流)

2023-02-27 22:02:16

什麼是流?如何理解流?下面本篇文章就來帶大家深入瞭解一下Nodejs中的流(Stream),希望對大家有所幫助!

stream 也就是流,可以理解為一連串的位元組像水流那樣的存在。按照官方檔案的解釋:

A stream is an abstract interface for working with streaming data in Node.js.

流是用於在 Node.js 中處理流資料,也就是連續位元組的抽象介面。 流有 4 種基本型別,本篇文章主要介紹其中兩種 —— 可讀流和可寫流。

可讀的(Readable)

我們可以通過 fs.createReadStream() 建立一個可讀流 readableStream,第 1 個引數可以是要讀取的檔案路徑,比如現有檔案 test.txt 內容為:

hello juejin
登入後複製

第 2 個引數(可選)可以傳入一個選項物件,用來控制讀取資料的起止位置等: 【相關教學推薦:】

const fs = require('fs')

const readableStream = fs.createReadStream('./test.txt', {
  start: 6,
  end: 11
})
登入後複製

注意,讀取的資料是包括了 startend 的。 在之前介紹 events 模組時說過,所有的流都是 EventEmitter 的範例。所以獲取資料是通過監聽 'data' 事件:

readableStream.on('data', data => {
  console.log(data)
  console.log(data.toString())
})
登入後複製

列印結果如下,預設是 Buffer 物件,可以通過 toString() 方法轉為字串:

1.png

注意,讀取資料時一次最多讀取 64 * 1024 位元組,如果想改變該數值,可以通過 highWaterMark 選項更改。另外還可以使用 pause() 進行暫停操作,使用 resume() 繼續讀取:

const readableStream = fs.createReadStream('./test.txt', {
  start: 6,
  end: 11,
  highWaterMark: 2 // 預設為 64 * 1024
})

readableStream.on('data', data => {
  console.log(data)
  console.log(data.toString())
  readableStream.pause() // 暫停讀取
  setTimeout(() => {
    readableStream.resume() // 恢復讀取
  }, 2000)
})
登入後複製

執行結果如下:

2.gif

除了 'data' 事件,可讀流還有其它一些事件,比如監聽檔案被開啟的 'open'(回撥會被傳入 fd 引數),監聽檔案讀取到 end(預設為讀取到最後)的 'end',監聽檔案關閉的 'close'(檔案讀取完會自動關閉):

readableStream.on('data', data => console.log(data))
readableStream.on('open', fd => console.log(`${fd}檔案開啟了`))
readableStream.on('end', () => console.log('檔案讀取到 end 位置了'))
readableStream.on('close', () => console.log('檔案已關閉'))
登入後複製

列印結果如下:

3.png

可寫的(Writable)

使用 fs.createWriteStream() 可以建立可寫流,第 1 個引數傳入要寫入的檔案,第 2 個同樣是用於設定的可選引數,這裡我們將 flags 由表示覆蓋寫入的 'w' 改為 'a',即追加寫入(如果還指定了寫入的起始位置 start,則為了相容 windows 系統, flags 應該寫成 'r+'):

const writableStream = fs.createWriteStream('test.txt', {
  flags: 'a'
})

writableStream.write('養成', err => console.log(`錯誤資訊:${err}`)) // 錯誤資訊:undefined
writableStream.write('寫作的')
writableStream.end('好習慣')
登入後複製

寫入資料是通過 write 方法,上方程式碼執行的結果就是在原本的 "hello juejin" 後新增上了 "養成寫作的好習慣"。最後一次寫入可以使用 end 方法,這樣就能監聽到可寫流的 'close' 事件了:

writableStream.on('close', () => {
  console.log('關閉')
})
登入後複製

否則,可寫流需要手動 writableStream.close() 關閉才能監聽到 'close' 事件。如果寫入成功,則作為 write()/end() 的第 2 個引數傳入的回撥的 err 就為 undefined

可讀流還有另外一些事件,比如檔案開啟時的 'open' 事件,當 close()end() 被呼叫後檔案寫入完成的 'finish' 事件。

可讀流與可寫流的連線

可讀流與可寫流可以通過 pipe 方法進行連線,實現對檔案的複製:

const readableStream = fs.createReadStream('./test.txt')
const writableStream = fs.createWriteStream('./copy.txt')

readableStream.pipe(writableStream)
登入後複製

如此,便能將 ./test.txt 內的文字複製到 ./copy.txt 中。

更多node相關知識,請存取:!

以上就是一文聊聊Node中的stream(流)的詳細內容,更多請關注TW511.COM其它相關文章!