【问题标题】:What's the fastest way to parse Node.JS buffer stream chunks' binary data into structures?将 Node.JS 缓冲流块的二进制数据解析为结构的最快方法是什么?
【发布时间】:2018-09-11 00:26:16
【问题描述】:

谷歌搜索“解析 nodejs 二进制流”我看到很多示例,当发出的数据完全符合预期的返回大小时,但是零示例说明如何处理下一个块包含来自第一个结构的剩余字节和新的标题。

当我期望类似以下内容时,解析二进制流的“正确”方法是什么:

record-length: 4bytes data1: 8bytes data2: 8bytes 4-byte-records[(record-length - 16) * 4];

数据将以各种大小的块形式出现。但是有没有办法调用 data.readUInt32(0) 并让它等待块填充?我不想写一个发射字节的管道阶段和一个接收状态机,这似乎非常错误。

这个必须解决,这是一个基本的概念。

帮助?

谢谢, 时间

【问题讨论】:

    标签: node.js buffer binary-data


    【解决方案1】:

    嗯...这可以使用stream..read 的异步版本和转换流来解决。

    现在您可以编写(并且可能会很有趣)您自己的版本,但我编写的框架 scramjet 已经具有 async read 并且我猜您希望让这变得简单。

    这是我能想到的最简单的方法,使用 AsyncGenerator:

    const {BufferStream} = require('scramjet'); // or es6 import;
    const input = BufferStream.from(getStreamFromSomewhere());
    
    const output = DataStream.from(async function* () {
      while(true) {
        const recordLength = (await input.whenRead(4)).readUInt32(0);  // read next chunk length
        if (!recordLength) return;                                     // stream ends here;
        const data1 = await input.whenRead(8);
        const data2 = await input.whenRead(8);
        const restOfData = [];
        for (let i = 0; i < recordLength; i += 4)
          restOfData.push((await input.read(4)).readUInt32(0))
    
        yield {data1, data2, restOfData};
      }
    })
      .catch(e => output.end()); // this is a handler for an option where any of the reads past
                                 // recordLength was to return null - perhaps should be better.
    

    这在 node v10 或 babel 中非常简单,但如果你愿意,我可以在此处添加非 AsyncGenerator 版本。

    【讨论】:

    • 谢谢。我有点沮丧,这需要另一个外部模块来处理看似基本的东西,但这成功了。
    • 我不会说它实际上需要scramjet - 但实现有点棘手。您可以获取源代码并查看我如何为AsyncGenerator 实现from,然后在没有框架的情况下重做。而且它只有 3 个依赖项,所以膨胀是最小的。
    猜你喜欢
    • 1970-01-01
    • 2012-04-14
    • 1970-01-01
    • 1970-01-01
    • 2015-12-28
    • 1970-01-01
    • 1970-01-01
    • 2013-08-08
    • 2021-04-12
    相关资源
    最近更新 更多