将NodeJS流消费到缓冲区并写入流的正确方法

问题描述 投票:3回答:1

我需要将可读流传递到缓冲区(要转换为字符串)和文件中。流来自node-fetch

NodeJS流具有两种状态:已暂停和正在流动。据我了解,一旦附加了'data'侦听器,流将更改为流模式。我想确保我读取流的方式不会丢失任何字节。

方法1:管道和从'data'中读取:

fetch(url).then(
  response =>
    new Promise(resolve => {
      const buffers = []
      const dest = fs.createWriteStream(filename)
      response.body.pipe(dest)
      response.body.on('data', chunk => buffers.push(chunk))
      dest.on('close', () => resolve(Buffer.concat(buffers).toString())
    })
)

方法2:使用直通流:

const { PassThrough } = require('stream')
fetch(url).then(
  response =>
    new Promise(resolve => {
      const buffers = []
      const dest = fs.createWriteStream(filename)
      const forFile = new PassThrough()
      const forBuffer = new PassThrough()
      response.body.pipe(forFile).pipe(dest)
      response.body.pipe(forBuffer)
      forBuffer.on('data', chunk => buffers.push(chunk))
      dest.on('close', () => resolve(Buffer.concat(buffers).toString())
    })
)

是否需要第二种方法,所以不会丢失数据?第二种方法是否浪费资源,因为可以缓冲另外两个流?或者,还有另一种方法来填充缓冲区并同时写入流吗?

node.js stream node-fetch
1个回答
1
投票
因此,写入dest流的任何块也将被发送到response.body.on('data'),您在其中缓冲这些块。无论如何,您应该侦听'error'事件,并在发生任何错误时拒绝。

虽然第二种模式可以工作,但您不需要它。

这是来自.pipe函数的一小段代码


src.on('data', ondata); function ondata(chunk) { debug('ondata'); var ret = dest.write(chunk); debug('dest.write', ret); if (ret === false) { // If the user unpiped during `dest.write()`, it is possible // to get stuck in a permanently paused state if that write // also returned false. // => Check whether `dest` is still a piping destination. if (((state.pipesCount === 1 && state.pipes === dest) || (state.pipesCount > 1 && state.pipes.indexOf(dest) !== -1)) && !cleanedUp) { debug('false write response, pause', state.awaitDrain); state.awaitDrain++; } src.pause(); } }
© www.soinside.com 2019 - 2024. All rights reserved.