从流或文件动态反序列化数据

deserialize data on the fly from stream or file

本文关键字:反序列化 数据 动态 文件      更新时间:2023-10-16

使用boost::serialize等公共库序列化和取消序列化数据结构或多或少都很容易。

但也有一种常见的情况,我只是简单地做一些类似(伪代码(的事情:

// receiver
NetworkInputStreamSerialzer stream;
while (1) // read new data objects from stream
{
    stream & data;
}

正如我所期望的,数据包必须已经从网络套接字完整地接收到。如果只能读取对象的一部分,则反序列化将失败。特别是在大数据集的情况下,TCP会对数据进行分段。

有没有一种通用的方法来处理这个问题?我在boost::serialize的文档中没有发现任何关于这个问题的提示。

由于这个问题适用于任何类型的流式数据,不仅适用于基于TCP的流式传输,也适用于一个程序发送数据而另一个程序接收数据的文件,因此必须有一个通用的解决方案,但我找不到任何解决方案。

我的问题不是专门用来促进的。我只是举个例子。

编辑:也许对我关于"碎片化"的措辞有更多的解释:

任何类型的数据,无论其以串行格式产生的大小如何,都可以在通过TCP传输或将其写入任何类型的文件时被分割成多个包。操作系统和我所知道的序列化库都不支持任何类型的"原子"写和读操作。

因此,如果从XML或JSON等人类可读格式中读取int,我可能会遇到这样的问题:如果在读取时"2"不在流或文件中,我会读取"11"而不是"112"。因此,以人类可读格式编写以下内容的长度也不是一个解决方案,因为当读取发生在内容字符串不完整的时刻时,大小信息本身可能会损坏。

[注意:我从你的Q中得到了一种感觉,你想要一个更好的boost::serialization替代品来满足你的特定情况。如果这不能回答你的Q,请告诉我,我会删除它。]

根据我自己的实践经验,建议使用谷歌协议缓冲区。以下是一些优点:

  1. 它可以在有线上使用(TCP等(
  2. 编写.proto文件以编写自己的文件的简单语法消息
  3. 跨平台&提供多种语言
  4. 与JSON&XML
  5. 生成标头&方便的getter、setter、serialize的源文件,反序列化&调试目的
  6. 易于序列化&反序列化--存储到&从文件检索

最后一点有点棘手。当存储在文件中时,您可能必须首先插入消息的长度,而在检索时,您必须首先读取该长度&然后使用CCD_ 2方法来读取确切的字节数。

上面的技巧和您在传输TCP时可能想要使用的技巧相同。在第一对字节中,可以传递长度。一旦确定了长度,您就可以始终收集剩余的碎片消息。