如何将一个NodeJS二进制缓冲区转换为JavaScript数组缓冲区?
当前回答
可以把ArrayBuffer看作是类型化的Buffer。
因此,ArrayBuffer总是需要一个类型(所谓的“数组缓冲区视图”)。通常,数组缓冲区视图有Uint8Array或Uint16Array类型。
Renato Mangini有一篇关于ArrayBuffer和String之间转换的好文章。
我在一个代码示例中总结了基本部分(用于Node.js)。它还展示了如何在类型化的ArrayBuffer和非类型化的Buffer之间进行转换。
function stringToArrayBuffer(string) {
const arrayBuffer = new ArrayBuffer(string.length);
const arrayBufferView = new Uint8Array(arrayBuffer);
for (let i = 0; i < string.length; i++) {
arrayBufferView[i] = string.charCodeAt(i);
}
return arrayBuffer;
}
function arrayBufferToString(buffer) {
return String.fromCharCode.apply(null, new Uint8Array(buffer));
}
const helloWorld = stringToArrayBuffer('Hello, World!'); // "ArrayBuffer" (Uint8Array)
const encodedString = new Buffer(helloWorld).toString('base64'); // "string"
const decodedBuffer = Buffer.from(encodedString, 'base64'); // "Buffer"
const decodedArrayBuffer = new Uint8Array(decodedBuffer).buffer; // "ArrayBuffer" (Uint8Array)
console.log(arrayBufferToString(decodedArrayBuffer)); // prints "Hello, World!"
其他回答
令人惊讶的是,在我的情况下(电子:发送缓冲区渲染器ArrayBuffer),这只是工作
function bufferToArrayBuffer(buffer: Buffer): ArrayBuffer {
return buffer.buffer as ArrayBuffer;
}
快了100倍
function bufferToArrayBuffer(buf) {
const ab = new ArrayBuffer(buf.length);
const view = new Uint8Array(ab);
for (let i = 0; i < buf.length; ++i) {
view[i] = buf[i];
}
return ab;
}
使用以下优秀的npm包:to-arraybuffer。
或者,您可以自己实现它。如果你的缓冲区叫buf,这样做:
buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength)
一种更快的写法
var arrayBuffer = new Uint8Array(nodeBuffer).buffer;
然而,在包含1024个元素的缓冲区上,这似乎比建议的toArrayBuffer函数慢了大约4倍。
这个代理将把缓冲区暴露为任何typedarray,没有任何副本。:
https://www.npmjs.com/package/node-buffer-as-typedarray
它只能在LE上工作,但是可以很容易地移植到be上。 而且,从来没有真正测试过这有多高效。
我尝试了上面的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++;
}