推荐使用缓冲区的方法?

时间:2017-08-26 17:56:11

标签: javascript node.js buffer

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

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

  

根据字符编码将字符串写入偏移量的buf   编码。 length参数是要写入的字节数。如果是buf   没有足够的空间来容纳整个字符串,只有一部分   将写入字符串的数量。但是,部分编码   字符不会被写入。

假设我想要写出比Buffer有空间的更多数据。增长它的推荐方法是什么?似乎没有.grow方法或类似方法。我可以调用Buffer.from(buf)来创建一个新的Buffer,但这看起来效率很低。

5 个答案:

答案 0 :(得分:3)

如果在开头不知道最终尺寸,您可以使用通常适用于dynamic arrays的方法:

  1. 使用初始大小
  2. 分配Buffer
  3. 将内容写入Buffer,直到有空格
  4. 当下一段内容不适合时,创建一个大小为两倍的新Buffer,将旧缓冲区的内容复制到新缓冲区,然后将新内容写入到最后
  5. 这样,在缓冲区末尾插入可以在O(1)分摊的时间内执行。

    此方法的变体通常用于Java,.NET中的可调整大小的列表,例如,在.NET的MemoryStream中,它对应于nodejs Buffer。您可以看到MemoryStream的实施方式 - here

    尺寸不一定要加倍。您可以选择不同的指数,例如3/2,如果你想节省一些空间。

    当然,最好的方法取决于您的使用案例,但这一方法表现良好。

答案 1 :(得分:2)

无法更改现有Buffer

的长度
  

Buffer类的实例类似于整数数组但是   对应于V8堆外部的固定大小的原始内存分配。   Buffer的大小在创建时建立,不可以   调整大小。

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

然而,您可以尝试使用/编写其他缓冲区实现或使用{Markerin建议的Buffer.concat

答案 2 :(得分:2)

我是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>

答案 3 :(得分:1)

如果你在每次添加后都不需要整个缓冲区的所有内容,我认为你可以在这里使用一个块数组(缓冲区)和Buffer.concat(chunks)来构建整个缓冲区。

const chunks = [];

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

const buf = Buffer.concat(chunks);

console.log(buf.toString()); 

答案 4 :(得分:0)

在创建缓冲区之前,只需抓取字符串的长度即可。

例如var buff = Buffer.alloc(someString.length)

记得缓冲区由于各种错误而进行了全面检查,检查了现已弃用的方法的官方页面:https://nodejs.org/api/buffer.html

这是危险的新缓冲区([0xE2,0xAD,0x90])(即将数组传递给新的缓冲区),如果传入某些数据,可能会导致溢出。