如何通过转换为 Uint8Array 保留源 Int16Array 值

How can source Int16Array values be retained though conversion to Uint8Array

我以这种格式通过函数传递数据

Int16Array > Uint8Array > Int16Array

如何让z和原来的x一样

var x = new Int16Array([17, -45]);
var y = new Uint8Array(x);
var z = new Int16Array(y);

想要将 z 设为 [ 17, -45 ]

编辑: 完整示例

const Readable = require('stream').Readable;

const rs = new Readable({
    objectMode: false,
    read(){}
});

var data = new Int16Array([17, -45]);
rs.push(data);

rs.on('data', function(chunk) {
    var result = new Int16Array(chunk);
});

我希望“结果”具有价值[17, -45]

push into a Readable stream from a typed array, use the Buffer.from method on its .buffer 创建缓冲区:

var data = new Int16Array([17, -45]);
var buf = Buffer.from(data.buffer);
rs.push(buf);

您在 data 事件处理程序中的 result 类型数组将需要再次从块的缓冲区构造:

rs.on('data', function(chunk) {
    var result = new Int16Array(chunk.buffer);
});

有关详细信息,请参阅文档中的 Buffers and TypedArrays

Number 16 bit (BE) In binary (BE) Note
17 0x00 0x11 00000000 00010001
-45 0xff 0xd3 11111111 11010011 255,211 in decimal
45 0x00 0xd3 00000000 00101101 The bits are flipped

一个包含两个值的 16 位 TypedArray 需要 2 * Int16Array.BYTES_PER_ELEMENT = 4 字节来存储数据。你可以自己检查一下:

console.log(
  arr16 = new Int16Array([17, -45]),
  arr16.buffer
);

[17, -45] // two elements (decimal)
...<11 00 d3 ff> // of 4 bytes total

注意:11 00 & d3 ff 相对于 00 11 & ff d3。顺序不同,因为表示是 Little Endian。别担心。

如果您将 buffer 传递给 Int8Array,您将得到:

console.log(
  arr8 = new Uint8Array( arr16.buffer ),
  arr8.buffer
);

[17, 0, 211, 255] // four elements (decimal)
...<11 00 d3 ff> // but same 4 bytes total

注意:事实上arr8和arr16都指完全相同的字节,所以如果你做arr16[0]=3arr8[0]也会变的!

倒数现在并不难想象:

new Int16Array( arr8.buffer );
[17, -45] // two elements (decimal)

因此,您的样本将是:

var x = new Int16Array([17, -45]);
var y = new Uint8Array(x.buffer); // the .buffer is important!
var z = new Int16Array(y.buffer);

console.log(x[1] === z[1]); // true;

如果您想转换为 Node.js 缓冲区,而不是 UintArray

// Important to use .buffer here, otherwise it'll use the decimal
// representation of your input, not the actual bytes!
const buffer = Buffer.from(arr16.buffer);

然后你需要添加:

new Int16Array( buffer.buffer )

因为如果你这样做:

new Int16Array( buffer );

那么你就是在有效地做到这一点:

const decimalRepresentationOfBytesInBuffer = [...buffer.values()];
new Int16Array( decimalRepresentationOfBytesInBuffer );
[17, 0, 11, 255] // four elements (decimal)
...<11 00 00 00 d3 00 ff 00> // of 8 bytes total