在 Node.js 中将 Buffer 转换为 ReadableStream

Posted

技术标签:

【中文标题】在 Node.js 中将 Buffer 转换为 ReadableStream【英文标题】:Converting a Buffer into a ReadableStream in Node.js 【发布时间】:2012-10-25 04:38:12 【问题描述】:

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

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

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

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

谢谢。

【问题讨论】:

【参考方案1】:

您可以为此使用标准的 NodeJS 流 API - stream.Readable.from

const  Readable  = require('stream');
const stream = Readable.from(buffer);

注意:如果缓冲区包含二进制数据,请勿将缓冲区转换为字符串 (buffer.toString())。这会导致二进制文件损坏。

【讨论】:

【参考方案2】:

对于 nodejs 10.17.0 及更高版本:

const  Readable  = require('stream');

const stream = Readable.from(myBuffer.toString());

【讨论】:

你是最棒的❤️ 是的,这是最好的。我不认为 .toString() 是必要的。 对于导入: const Readable = require('stream') 这对图片文件有影响吗? 它适用于 OP 描述的情况,但如果缓冲区包含二进制数据.toString() 会损坏它【参考方案3】:

试试这个:

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

来源: 布赖恩·曼奇尼 -> http://derpturkey.com/buffer-to-stream-in-node/

【讨论】:

【参考方案4】:

这是我的简单代码。

import  Readable  from 'stream';

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

【讨论】:

【参考方案5】:

您不需要为单个文件添加整个 npm 库。我将它重构为打字稿:

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(如上所述的最佳选择)。

【讨论】:

【参考方案6】:

这是一个使用 streamifier 模块的简单解决方案。

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

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

【讨论】:

另一个等效的替代方案是 tostream: const toStream = require('tostream'); toStream(new Buffer ([97, 98, 99])).pipe(process.stdout); @YushinWashio 绝对。 Node 中有很多可用的模块。【参考方案7】:

这样的……

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

【讨论】:

push()_read() 方法中的缓冲区不是更正确吗? IE。 readable._read = () => readable.push(buffer); readable.push(null); 。不确定这是否重要,但允许流管理数据输入的时间似乎不太可能遇到意外行为。除此之外,这应该是公认的答案,因为它不依赖于 3rd 方模块。 一般来说,你是对的,但对于这个特定的用例,我不会在 read 方法中使用 push。从概念上讲,我认为_read 应该保留用于从底层来源“收集”数据。在这种情况下,我们不仅有内存中的数据,而且不需要转换。因此,对于将数据包装在流中,我会这样做,但对于在流中转换或累积数据,该逻辑将发生在 _read 方法中。 你的底层来源是缓冲区;) @FranckFreiburger 是的,但你不是从那个来源“收集”数据,它已经在内存中,你总是会一口气消耗掉它,你不会把它拉进去按需提供。【参考方案8】:

您可以像这样使用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,所以会引入一定的延迟。

【讨论】:

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

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

Gabriel Llamas 在这个答案中建议streamifier:How to wrap a buffer as a stream2 Readable stream?

【讨论】:

以上是关于在 Node.js 中将 Buffer 转换为 ReadableStream的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Node.js 中将 NTLM 凭据转换为 Kerberos 令牌

如何在node js中将promise转换为回调?

如何在 node.js 中将位字符串转换为 base64?

在node.js和GraphicsMagick中将tiff转换为jpeg

Node.js的Buffer(缓冲区)和Stream

如何在 Node JS 中将原始 PCM 流转换为 Discord 机器人的 opus 或 wav 流?