如何将一个NodeJS二进制缓冲区转换为JavaScript数组缓冲区?
当前回答
Buffer是ArrayBuffer的视图。你可以使用buffer属性访问内部包装的ArrayBuffer。
这是共享内存,不需要复制。
const arrayBuffer = theBuffer.buffer
如果你想要数据的副本,从原始的Buffer(不是从包装的ArrayBuffer)创建另一个Buffer,然后引用它的包装的ArrayBuffer。
const newArrayBuffer = Buffer.from(theBuffer).buffer
作为参考,从另一个方向,从ArrayBuffer到Buffer
const arrayBuffer = getArrayBuffer()
const sharedBuffer = Buffer.from(arrayBuffer)
const copiedBuffer = Buffer.from(sharedBuffer)
const copiedArrayBuffer = copiedBuffer.buffer
其他回答
NodeJS,在某一时刻(我想是v0.6.x)有ArrayBuffer支持。我在这里创建了一个用于base64编码和解码的小库,但自从更新到v0.7以来,测试(在NodeJS上)失败了。我正在考虑创建一些标准化的东西,但在此之前,我认为应该使用节点的本机缓冲区。
Buffer的实例也是node.js 4中Uint8Array的实例。X和更高。因此,最有效的解决方案是直接访问缓冲区自己的.buffer属性,如https://stackoverflow.com/a/31394257/1375574。Buffer构造函数也接受一个ArrayBufferView参数,如果你需要走另一个方向。
注意,这不会创建一个副本,这意味着对任何ArrayBufferView的写入都将写入原始的Buffer实例。
In older versions, node.js has both ArrayBuffer as part of v8, but the Buffer class provides a more flexible API. In order to read or write to an ArrayBuffer, you only need to create a view and copy across.
从Buffer到ArrayBuffer:
function toArrayBuffer(buffer) {
const arrayBuffer = new ArrayBuffer(buffer.length);
const view = new Uint8Array(arrayBuffer);
for (let i = 0; i < buffer.length; ++i) {
view[i] = buffer[i];
}
return arrayBuffer;
}
从ArrayBuffer到Buffer:
function toBuffer(arrayBuffer) {
const buffer = Buffer.alloc(arrayBuffer.byteLength);
const view = new Uint8Array(arrayBuffer);
for (let i = 0; i < buffer.length; ++i) {
buffer[i] = view[i];
}
return buffer;
}
"From ArrayBuffer to Buffer"可以这样做:
var buffer = Buffer.from( new Uint8Array(arrayBuffer) );
没有依赖,最快,Node.js 4。X及以后
Buffers是Uint8Arrays,所以你只需要切片(复制)它的支持ArrayBuffer的区域。
// Original Buffer
let b = Buffer.alloc(512);
// Slice (copy) its segment of the underlying ArrayBuffer
let ab = b.buffer.slice(b.byteOffset, b.byteOffset + b.byteLength);
切片和偏移量是必需的,因为小缓冲区(默认小于4 kB,池大小的一半)可以是共享ArrayBuffer上的视图。如果没有切片,你可能会得到一个ArrayBuffer,其中包含了来自另一个Buffer的数据。请参阅文档中的解释。
如果你最终需要一个TypedArray,你可以创建一个而不复制数据:
// Create a new view of the ArrayBuffer without copying
let ui32 = new Uint32Array(b.buffer, b.byteOffset, b.byteLength / Uint32Array.BYTES_PER_ELEMENT);
没有依赖,速度适中,适用于任何版本的Node.js
使用Martin Thomson的答案,它在O(n)时间内运行。(参见我对他关于非优化的回答的回复。使用DataView很慢。即使你需要转换字节,也有更快的方法。)
依赖,快速,Node.js≤0.12或iojs 3.x
您可以使用https://www.npmjs.com/package/memcpy向任何一个方向(缓冲区到ArrayBuffer和返回)。它比这里发布的其他答案要快,而且是一个写得很好的库。节点0.12到iojs 3。X要求ngossen's fork(见此)。
我尝试了上面的Float64Array,它只是没有工作。
我最终意识到,真正的数据需要读入正确的块视图。这意味着一次从源Buffer读取8个字节。
总之,这是我最后得到的……
var buff = new Buffer("40100000000000004014000000000000", "hex");
var ab = new ArrayBuffer(buff.length);
var view = new Float64Array(ab);
var viewIndex = 0;
for (var bufferIndex=0;bufferIndex<buff.length;bufferIndex=bufferIndex+8) {
view[viewIndex] = buff.readDoubleLE(bufferIndex);
viewIndex++;
}
推荐文章
- 如何删除和清除所有的本地存储数据
- 如何从给定的html字符串中删除前导和尾随空白?
- 如何为KnockoutJS调试模板绑定错误?
- 将一个二进制的NodeJS Buffer转换为JavaScript的ArrayBuffer
- 检测浏览器标签是否有焦点
- JavaScript在数组中
- 如何从JavaScript中使用正则表达式的字符串中剥离所有标点符号?
- 如何修改标签文本?
- 如何获得十六进制颜色值而不是RGB值?
- 字符串strip() JavaScript?
- 如何将一个标题转换为jQuery的URL段塞?
- 获取对象的第一个索引
- 我如何用javascript编程点击链接?
- JavaScript:客户端验证与服务器端验证
- React钩子:从回调中访问最新状态