在 Node.js 中将 Buffer 转换为 ReadableStream

IT技术 javascript node.js stream buffer
2021-02-03 08:23:48

我对 Buffers 和 ReadableStreams 还很陌生,所以也许这是一个愚蠢的问题。我有一个将 a 作为输入的库ReadableStream,但我的输入只是一个 base64 格式的图像。我可以Buffer像这样转换我拥有的数据

var img = new Buffer(img_string, 'base64');

但我不知道如何将其转换为 aReadableStream或将Buffer我获得的转换为ReadableStream.

有没有办法做到这一点,还是我试图实现不可能的目标?

谢谢。

6个回答

对于 nodejs 10.17.0 及更高版本:

const { Readable } = require('stream');

const stream = Readable.from(myBuffer.toString());
对于导入: const { Readable } = require('stream')
2021-03-19 08:23:48
这对图像文件有任何影响吗?
2021-03-20 08:23:48
你是最棒的❤️
2021-03-21 08:23:48
是的,这是最好的。我不认为 .toString() 是必要的。
2021-04-09 08:23:48

像这样的东西......

import { Readable } from 'stream'

const buffer = new Buffer(img_string, 'base64')
const readable = new Readable()
readable._read = () => {} // _read is required but you can noop it
readable.push(buffer)
readable.push(null)

readable.pipe(consumer) // consume the stream

在一般过程中,可读流的_read函数应该从底层源收集数据,并push逐步确保您不会在需要之前将大量源收集到内存中。

在这种情况下,虽然您已经在内存中拥有源代码,但_read不是必需的。

推送整个缓冲区只是将其包装在可读流 api 中。

您的基础来源是缓冲区;)
2021-03-28 08:23:48
方法push()内部的缓冲区不是更正确_read()吗?readable._read = () => {readable.push(buffer); readable.push(null);}不确定这很重要,但允许流管理数据输入的时间似乎不太可能遇到意外行为。除此之外,这应该是公认的答案,因为它不依赖于 3rd 方module。
2021-03-29 08:23:48
一般来说,你是对的,但对于这个特定的用例,我不会pushread方法中。从概念上讲,我认为_read应该保留用于从底层来源“收集”数据。在这种情况下,我们不仅在内存中有数据,而且不需要转换。因此,对于在流中包装数据,我会这样做,但是对于在流中转换或累积数据,该逻辑将在_read方法中发生
2021-04-09 08:23:48
@FranckFreiburger 是的,但是您不是从该来源“收集”数据,它已经在内存中,并且您总是会一次性消耗所有数据,而不是按需提取。
2021-04-12 08:23:48

Node Stream Buffer显然是为测试而设计的;无法避免延迟使其成为生产使用的糟糕选择。

Gabriel Llamas在这个答案中建议使用流化器How to wrap a buffer as a stream2 Readable stream?

您可以使用Node Stream Buffers创建一个 ReadableStream,如下所示:

// Initialize stream
var myReadableStreamBuffer = new streamBuffers.ReadableStreamBuffer({
  frequency: 10,      // in milliseconds.
  chunkSize: 2048     // in bytes.
}); 

// With a buffer
myReadableStreamBuffer.put(aBuffer);

// Or with a string
myReadableStreamBuffer.put("A String", "utf8");

频率不能为 0,因此这会引入一定的延迟。

确认它有效 - 在查找如何将文件缓冲区转换为流时发现了这一点。
2021-03-15 08:23:48
@UpTheCreek 我无法更改它,因为这是属性名称,单位是毫秒。
2021-03-24 08:23:48
毫秒不是频率的度量 - 我想它们是指周期。
2021-04-04 08:23:48
谢谢,虽然有点晚。我不记得我是如何解决这个问题的,但这看起来是一个不错的解决方案。如果有人证实这一点,那就太好了。我记得在这个转换中发现零。
2021-04-08 08:23:48
如果您有处理文件的文件,您应该立即打开文件读取流:nodejs.org/api/fs.html#fs_fs_createreadstream_path_options
2021-04-13 08:23:48

您不需要为单个文件添加整个 npm lib。我将它重构为typescript:

import { Readable, ReadableOptions } from "stream";

export class MultiStream extends Readable {
  _object: any;
  constructor(object: any, options: ReadableOptions) {
    super(object instanceof Buffer || typeof object === "string" ? options : { objectMode: true });
    this._object = object;
  }
  _read = () => {
    this.push(this._object);
    this._object = null;
  };
}

基于节点流化器(如上所述的最佳选择)。