如何将一个NodeJS二进制缓冲区转换为JavaScript数组缓冲区?


当前回答

这个代理将把缓冲区暴露为任何typedarray,没有任何副本。:

https://www.npmjs.com/package/node-buffer-as-typedarray

它只能在LE上工作,但是可以很容易地移植到be上。 而且,从来没有真正测试过这有多高效。

其他回答

没有依赖,最快,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(见此)。

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上)失败了。我正在考虑创建一些标准化的东西,但在此之前,我认为应该使用节点的本机缓冲区。

可以把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!"

使用以下优秀的npm包:to-arraybuffer。

或者,您可以自己实现它。如果你的缓冲区叫buf,这样做:

buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength)