假设我正在 Node.js 中构造一个可变长度的字符串或一系列字节。 buf.write 的文档说:
https://nodejs.org/api/buffer.html#buffer_buf_write_string_offset_length_encoding
根据中的字符编码将字符串写入到偏移量处的buf 编码。长度参数是要写入的字节数。如果缓冲 没有足够的空间来容纳整个字符串,仅包含部分字符串 将写入的字符串数量。然而,部分编码 字符不会被写入。
假设我想要写入的数据多于缓冲区的空间。推荐的种植方式是什么?似乎没有
.grow
方法或类似方法。我可以调用 Buffer.from(buf)
创建一个新的 Buffer,但这似乎效率很低。
如果您在每次添加后不需要整个缓冲区的所有内容,我认为您可以在此处使用块(缓冲区)数组,并在必要时
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());
当开始时不知道最终大小时,您可以使用通常应用于动态数组的方法:
Buffer
一些初始大小Buffer
Buffer
,大小增加一倍,将旧缓冲区的内容复制到新缓冲区,并像以前一样将新内容写入末尾这样,可以在
O(1)
摊销时间内执行在缓冲区末尾的插入。
这种方法的变体通常用于 Java、.NET 或其他可调整大小的列表中。在.NET中的
MemoryStream
对应于nodejs Buffer
。您可以在这里了解
MemoryStream
是如何实现的。
尺寸不一定要加倍。您可以选择不同的指数,例如
3/2
,如果你想节省一些空间。
当然,最好的方法取决于您的用例,但这种方法总体来说表现良好。
无法更改现有长度
Buffer
Buffer 类的实例类似于整数数组,但是 对应于 V8 堆之外的固定大小的原始内存分配。 Buffer的大小在创建时就确定了,不能改变 调整大小。
https://nodejs.org/api/buffer.html#buffer_buffer
但是,您可以尝试使用/编写一些其他缓冲区实现或使用
Buffer.concat
正如 Nik Markin 建议的那样
我对 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>
我尝试了 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)