将 Node.JS 缓冲流块的二进制数据解析为结构的最快方法是什么?

What's the fastest way to parse Node.JS buffer stream chunks' binary data into structures?

谷歌搜索 "parse nodejs binary stream" 当发出的数据完全符合预期的 return 大小时,我看到了很多示例,但是当下一个块包含剩余字节时如何处理这种情况的示例为零来自第一个结构和新的header。

当我期望像这样的东西时,"right" 解析二进制流的方法是什么:

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

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

这个问题必须解决,这是一个非常基本的概念。

帮忙?

谢谢, 点

嗯...这可以使用 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.

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