推荐的增长缓冲区的方法?

问题描述 投票:0回答:5

假设我正在 Node.js 中构造一个可变长度的字符串或一系列字节。 buf.write 的文档说:

https://nodejs.org/api/buffer.html#buffer_buf_write_string_offset_length_encoding

根据中的字符编码将字符串写入到偏移量处的buf 编码。长度参数是要写入的字节数。如果缓冲 没有足够的空间来容纳整个字符串,仅包含部分字符串 将写入的字符串数量。然而,部分编码 字符不会被写入。

假设我想要写入的数据多于缓冲区的空间。推荐的种植方式是什么?似乎没有

.grow
方法或类似方法。我可以调用
Buffer.from(buf)
创建一个新的 Buffer,但这似乎效率很低。

javascript node.js buffer
5个回答
10
投票

如果您在每次添加后不需要整个缓冲区的所有内容,我认为您可以在此处使用块(缓冲区)数组,并在必要时

Buffer.concat(chunks)
构建整个缓冲区。

const chunks = [];

chunks.push(Buffer.from([0xE2, 0xAD, 0x90]));  // star
chunks.push(Buffer.from([0xF0, 0x9F, 0x9A, 0x80])); // rocket

const buf = Buffer.concat(chunks);

console.log(buf.toString()); 

6
投票

当开始时不知道最终大小时,您可以使用通常应用于动态数组的方法

  1. 分配
    Buffer
    一些初始大小
  2. 只要有空间就将内容写入
    Buffer
  3. 当下一段内容放不下时,创建一个新的
    Buffer
    ,大小增加一倍,将旧缓冲区的内容复制到新缓冲区,并像以前一样将新内容写入末尾

这样,可以在

O(1)
摊销时间内执行在缓冲区末尾的插入。

这种方法的变体通常用于 Java、.NET 或其他可调整大小的列表中。在.NET中的

MemoryStream
对应于nodejs
Buffer
。您可以在
这里
了解MemoryStream是如何实现的。

尺寸不一定要加倍。您可以选择不同的指数,例如

3/2
,如果你想节省一些空间。

当然,最好的方法取决于您的用例,但这种方法总体来说表现良好。


2
投票

无法更改现有长度

Buffer

Buffer 类的实例类似于整数数组,但是 对应于 V8 堆之外的固定大小的原始内存分配。 Buffer的大小在创建时就确定了,不能改变 调整大小。

https://nodejs.org/api/buffer.html#buffer_buffer

但是,您可以尝试使用/编写一些其他缓冲区实现或使用

Buffer.concat
正如 Nik Markin 建议的那样


1
投票

我对 Node JS 很陌生,但是当我尝试遵循代码时它起作用了。
[不确定它是否会造成任何内存泄漏或是否存在任何进一步的问题...]

'use strict';

var tempBuffer = [];

var i = 0;

tempBuffer.push(i++);
tempBuffer.push(i++);
tempBuffer.push(i++);
tempBuffer.push(i++);
tempBuffer.push(i++);
tempBuffer.push(i++);

console.log('buf4 before creation: ');
console.log(buf4);

var buf4 = Buffer.from(tempBuffer);
console.log('buf4 after creation (type):' + typeof(buf4));

console.log('buf4 after creation (data):');
console.log(buf4);

tempBuffer.push(i++);
tempBuffer.push(i++);
tempBuffer.push(i++);
tempBuffer.push(i++);
tempBuffer.push(i++);
tempBuffer.push(i++);

buf4 = Buffer.from(tempBuffer);

console.log('buf4 after expantion (data):');
console.log(buf4);

这是输出:

buf4 before creation:
undefined
buf4 after creation (type):object
buf4 after creation (data):
<Buffer 00 01 02 03 04 05>
buf4 after expantion (data):
<Buffer 00 01 02 03 04 05 06 07 08 09 0a 0b>

0
投票

我尝试了 Nik 的答案,效果很好,但在一些大的

Buffer
(大图像位图)上,我耗尽了堆并出现错误!

我的运气比较好:

// create instance of big enough buffer
const biggerBuffer = Buffer.alloc(smallerBufferLength + diffLen);
// copy stuff across
const count = smallerBuffer.copy(biggerBuffer);
// allow old buffer to be GC'ed
smallerBuffer = null;

剩余空间默认用零填充:https://nodejs.org/api/buffer.html#static-method-bufferallocsize-fill-encoding.

:o)

© www.soinside.com 2019 - 2024. All rights reserved.