在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很慢,现在有阵列缓冲区的类型数组。 (与Buffers不同)。有没有更好的方法从这个缓冲区创建一个int数组。
更新1
根据反馈,我做了以下
var arr = new Int16Array(spectrum.buffer)
这给了我合适的类型但是字节被交换了。频谱缓冲区以big endian存储。
&LT;缓冲e1 d7 e0 b9 e3 52 e2 d5 e2 ed e2 92 e2 d6 e2 97 e3 04 e1 95 e1 e2&gt; e1 d8 e3 14 e2 fd e1 ed e2 d3 e3 09 e1 9f e2 14 e2 f2 e2 54 e2 1f e2 54&gt; e2 06 e2 8a ...&gt;
前三个数字见于-10271,-17952,21219
然而,它们的变化不应该那么大,三者都应该是负数。
第一个数字应该是-7721(两个补码总是让我困惑)
节点6上的Int16Array也是假设大端或小端,我该如何处理它。
答案 0 :(得分:1)
不确定。 Node.js缓存are a special instance的Uint8Array
。
因此,如果您想创建Int16Array
的实例,可以创建缓冲区的副本:
var int16Arr = new Int16Array(spectrum_buffer);
或创建一个引用相同底层缓冲区的新数组,这意味着您不必复制所有数据:
var int16Arr = new Int16Array(spectrum_buffer.buffer);
更新
键入的数组默认使用本机字节顺序。如果需要指定字节顺序,可以使用较低级别的接口:DataView
。
DataView
是Buffer的包装器,可让您完全控制数据的访问方式。在您的情况下,您可能希望使用getInt16
方法并根据数据需要设置endianess标志:
var littleEndian = true; // or false, depends on your needs
var dataView = new DataView(spectrum.buffer);
dataView.getInt16(offset, littleEndian);
答案 1 :(得分: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];
}