【问题标题】:Map binary buffer to Int16Array or Int32Array将二进制缓冲区映射到 Int16Array 或 Int32Array
【发布时间】:2021-08-21 21:59:29
【问题描述】:

假设我将二进制文件读入 Buffer 对象,如下行所示

const fs = require('fs');
var file_content = fs.readFileSync(fileNamePath);

现在假设 file_content 等于:

<Buffer 50 4b 03 04 01 2b b4 52 >

在十进制中,这些字节值是:

<Buffer 80 75 3 4 1 43 180 82 >

这些是 8 个字节。我需要将它们转换成一个 int 数组,Int16Array 或 Int32Array。

在 Int16Array 的情况下。我期待以下值:

Int16Array(4) [20555, 772, 299, 46162]

对于 Int32Array 我期待:

Int32Array(2) [1347093252, 012bb452]

与上面的示例一样,我希望在转换为 Int16Array 时,这 8 个字节将被转换为仅 4 个 Int,因为每个 Int 占用两个字节。在 Int32Array 的情况下,我预计只有 2 个,因为每个应该占用 4 个字节。

但是,当我执行以下操作时:

var int16a = Int16Array.from(file_content);
var int32a = Int32Array.from(file_content);
console.log(int16a, int32a);

输出是:

Int16Array(8) [ 80, 75, 3,  4, 1, 43, 180, 82 ] 
Int32Array(8) [ 80, 75, 3,  4, 1, 43, 180, 82 ]

这样在这两种情况下它都只向每个 Int 转换一个字节。

【问题讨论】:

  • 那么你的问题是什么?构造类型化数组的代码在哪里?什么不起作用?
  • 好的,我更新了我的问题。问题是,例如,当我执行 Int16Array.from() 时,它会从 Int 中的 Buffer 中返回每个字节,而不是实际上为每个(16 位)占用 2 个字节

标签: javascript binary


【解决方案1】:

不要使用from,它会迭代节点缓冲区的字节并将它们作为整数放入类型化数组中。

相反,construct a typed array 作为node Buffer's underlying .buffer 的视图:

const fs = require('fs');
const file_content = fs.readFileSync(fileNamePath);

const int16a = new Int16Array(file_content.buffer, file_content.byteOffset, file_content.length/2);
const int32a = new Int32Array(file_content.buffer, file_content.byteOffset, file_content.length/4);
console.log(int16a, int32a);

【讨论】:

  • 我明白了!这就说得通了! :D 我不确定为什么结果仍然不完全符合预期?例如,当我使用您为 Int16Array 提供的这种方法时,前两个字节 0x50 和 0x4b 变为值 0x4b50 而不是 0x504b 的 int。这样字节的顺序由于某种原因被颠倒了......
  • @Menas 看起来您的机器与文件中的编码数据具有不同的字节顺序。您可以使用Buffer methodsDataView
【解决方案2】:

除非您必须让存储阵列具有 16 位类型,否则我更喜欢使用 Buffer 方法,例如 readInt16LE()readInt32BE() 来生成 numberbigint 原语。它还使您可以更好地控制字节顺序,Int16Array 等使用平台字节序。您还可以将最多 6 个字节(48 位)的整数读入number 原语。

将示例缓冲区用于 16 位整数:

var shorts = [];
for (let offset = 0; offset < file_content.length; offset += 2)
    shorts.push(file_content.readInt16LE(offset));

对于 32 位:

var ints = [];
for (let offset = 0; offset < file_content.length; offset += 4)
    ints.push(file_content.readInt32LE(offset));

示例 6 个字节: var six = file_content.readIntLE(0, 6);

注意字节顺序和符号。查看所有功能here

【讨论】:

    猜你喜欢
    • 2020-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-26
    • 2010-09-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多