Node.js缓冲区转换为类型化数组

3

在Node.js中,我有一个Buffer(它被存储为MySQL中的blob,并使用sequelize检索)。 我知道这个Buffer是一组16位整数。过去我已经用for循环解析了代码。

    var spectrum_buffer = spectrums[idx]["spectrum"];//this is a buffer
    var parsed_spectrum = [];
    for (var i = 0; i < spectrum_buffer.length / 2; i++) {
        parsed_spectrum[i] = spectrum_buffer.readInt16BE(i * 2);
    }

我听说readInt16BE很慢,现在有针对ArrayBuffers的TypedArrays(与Buffers不同)。是否有更好的方法从此缓冲区创建整数数组。
更新1
根据反馈,我做了以下操作。
var arr = new Int16Array(spectrum.buffer)

这让我获得了正确的类型,但是字节被交换了。频谱缓冲区以大端方式存储。

< Buffer e1 d7 e0 b9 e3 52 e2 d5 e2 ed e2 92 e2 d6 e2 97 e3 04 e1 95 e1 e2 > e1 d8 e3 14 e2 fd e1 ed e2 d3 e3 09 e1 9f e2 14 e2 f2 e2 54 e2 1f e2 54 > e2 06 e2 8a ... >

前三个数字显示为-10271、-17952、21219。

然而,它们不应该有那么大的差异,所有三个数字都应该是负数。

第一个数字应该是-7721(二进制补码总是让我感到困惑)。

因此,在node 6上,Int16Array是使用大端还是小端,我该如何处理?


注意:https://nodejs.org/api/buffer.html#buffer_buffers_and_typedarray 看起来很有可能,如果您在填充缓冲区之前创建了类型化数组。 - T.J. Crowder
只是让你知道,我更新了我的答案。如果需要使用特定的字节序读取数据,则可以使用更低级别的接口。 - Mike Cluck
2个回答

4
当然。Node.js缓冲区是Uint8Array的特殊实例之一
因此,如果您想创建一个Int16Array实例,您可以创建缓冲区的副本:
var int16Arr = new Int16Array(spectrum_buffer);

或者创建一个新的数组,引用相同的底层缓冲区,这意味着您不必复制所有数据:
var int16Arr = new Int16Array(spectrum_buffer.buffer);

更新:
类型化数组默认使用本机字节顺序。如果您需要指定字节顺序,可以使用更低级别的接口:DataViewDataView是一个包装器,围绕缓冲区提供了对数据访问的完全控制。在您的情况下,您将希望使用getInt16方法,并根据您的数据需要设置大小端标志:
var littleEndian = true; // or false, depends on your needs
var dataView = new DataView(spectrum.buffer);
dataView.getInt16(offset, littleEndian);

4
上述两个 new Int16Array 调用都会按每个字节创建1个值,而不是从字节数据重新创建类型化数组。 - Tomáš Zato
如果您想从字节数据重新创建一个类型化数组,请参阅此问题被接受的答案了解背景,然后阅读"最佳解决方案"链接了解如何完成这个操作。 - Venryx

0

试试这个:

//this is a buffer
var spectrum_buffer = spectrums[idx]["spectrum"];

// these two views share same memory
var int16view = new Int16Array(spectrum_buffer); 
var uint8view = new Uint8Array(spectrum_buffer);

var parsed_spectrum = [];

for (var i = 0; i < int16view.length; i++) {
    // swap byte order
    [uint8view[i*2], uint8view[i*2+1]] = [uint8view[i*2+1], uint8view[i*2]]; // ES6 swap
    // read swapped bytes as Int16
    parsed_spectrum[i] = int16view[i];
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接