在Node.js中将缓冲区转换为ReadableStream


77

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

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

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

有办法做到这一点,还是我在努力实现不可能?

谢谢。

Answers:


29

您可以使用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,因此会引入一定的延迟。


谢谢,尽管有点晚。我不记得我是如何解决问题的,但这看起来是一个不错的解决方案。如果有人确认这一点,那就太好了。我记得找到有关此转换的零。
Masiar 2013年

1
确认它有效-在查找如何将文件缓冲区转换为流时发现了这一点。
杰克·劳森

如果您有文件要处理文件,则应该直接使用以下命令
vanthome

2
毫秒不是频率的量度-我认为它们是指周期。
UpTheCreek

@UpTheCreek我无法更改它,因为这是属性名称,单位为毫秒。
vanthome

61

像这样的东西

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中。


2
方法push()内部的缓冲区不是更正确_read()吗?即readable._read = () => {readable.push(buffer); readable.push(null);}。不确定是否很重要,但是让流管理数据馈入的时间似乎不太可能发生意外行为。除此之外,这应该是公认的答案,因为它不依赖于第三方模块。
broofa

1
通常,您是对的,但是对于这种特定的用例,我不会pushread方法中使用。从概念上讲,我认为_read应保留用于从底层来源“收集”数据。在这种情况下,我们不仅将数据存储在内存中,而且不需要转换。因此,对于将数据包装在流中,这就是我的方法,但是对于在流中转换或累积数据,该逻辑将在_read方法中发生。
Mr5o1

您的基础资源就是缓冲区;)
弗兰克·弗赖堡

@FranckFreiburger是的,但是您不是从该源中“收集”数据,它已经在内存中,并且您总是要一次性使用所有数据,而不是按需提取数据。
Mr5o1



5

这是使用流化器模块的简单解决方案。

const streamifier = require('streamifier');
streamifier.createReadStream(new Buffer ([97, 98, 99])).pipe(process.stdout);

您可以使用字符串,缓冲区和对象作为其参数。


1
另一个等效的替代方法是tostreamconst toStream = require('tostream'); toStream(new Buffer ([97, 98, 99])).pipe(process.stdout);
Yushin Washio

@YushinWashio一定。Node中提供了大量模块。
Shwetabh Shekhar

5

您无需为单个文件添加整个npm lib。我将其重构为打字稿:

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;
  };
}

基于node-streamifier(如上所述的最佳选择)。


5

这是我的简单代码。

import { Readable } from 'stream';

const newStream = new Readable({
                    read() {
                      this.push(someBuffer);
                    },
                  })

0

试试这个:

const Duplex = require('stream').Duplex;  // core NodeJS API
function bufferToStream(buffer) {  
  let stream = new Duplex();
  stream.push(buffer);
  stream.push(null);
  return stream;
}

资料来源:Brian Mancini-> http://derpturkey.com/buffer-to-stream-in-node/

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.