6

我有一个关于数据结构序列化的问题。数据结构的序列化有很多可能性(也称为编组放气,请参阅wiki-article)。每种编程语言、框架、标准或库似乎都带有自己的序列化方法。许多人还定义了自己的数据/接口描述语言(我更喜欢仅在代码内部定义的语言依赖数据结构)。仅举几例(参见wiki 文章):COM IDL、CORBA IDL、Thrift IDL、google 协议缓冲区“.proto”、XSD、ASN.1 IDL 等等。其中一些序列化能够生成语言本机数据结构和用于序列化和反序列化这些结构的代码。

我对这个主题做了一些研究,但我仍然没有决定。所以我的问题是:我 应该使用哪个序列化?

我的要求可扩展性、空间效率(至少是二进制)、有效访问数据、易于使用(可能使用生成的代码和 getter 和 setter)和 c++ 兼容性。

可扩展性应该提供向前和向后的兼容性。更具体地说,我编写的数据格式通常会随着时间的推移而增长,因为我添加了新的数据字段,这是我在开发之初无法预见的。现在我希望能够使用更新的软件版本从过时的格式中读取存储的数据,在旧存储数据中找不到的数据字段可以填充默认值或其他内容。另一方面,我希望能够读取用新描述写入的数据。然后,使用“旧”数据描述编译的软件应忽略未知数据字段(可能会产生一些警告)。

有什么建议吗?关于该主题的进一步阅读的建议也将不胜感激。

- - 编辑 - -

1) boost::serialization 似乎很流行。它有一些非常好的特性,文档非常好,语法似乎很简单。也许我有点挑剔,但有些事情我不喜欢:我看不出它如何处理前向兼容性(见4)。我更喜欢生成的代码。

2) google protobuf 似乎更适合我的需求,但我还没有深入研究它们。它们似乎很好地处理了向前和向后的兼容性(参见5)。他们有不同语言的代码生成器,开发人员知道非常相似的概念,例如(参见常见问题解答)。我将对 protobufs 进行更深入的研究。

3)提升精神似乎不是我搜索的东西。

4

2 回答 2

2

我使用了一段时间的 boost 的序列化库——它是可扩展的、高效的,并且支持对你正在序列化的每个对象进行单独的版本控制。所有这些特征当然意味着它是一个复杂的野兽,需要一些时间才能正确学习。也不是那么容易编译。而且,如果您尝试将其带到不受官方支持的平台上,请期待调试一些非常复杂的代码。跨平台的文件兼容性可能有点不稳定,并且前向兼容性不起作用。总体而言,如果您需要应用程序实例相互通信,boost 序列化通常不是一个好的选择。尽管如此,对于正确的项目来说,这并不是那么糟糕。

http://www.boost.org/doc/libs/1_46_0/libs/serialization/doc/index.html

Boost 还有更新的 Spirit 库,用于更通用的解析/输出,但我没有使用它,也不会根据第一印象推荐它 - 甚至需要一些挖掘才能理解这个特殊命名的库的含义。

最后,对于更简单的项目来说,滚动你自己的序列化库也可能不是一个坏选择——这并不难,而且你得到了你需要的特性。令人失望的是,C++ 世界似乎仍然没有充分解决序列化问题,但这是我上次不得不决定序列化功能时得出的结论。不过,暂时使用 boost 的序列化可以很好地了解我自己实现的目标。

于 2011-02-25T12:01:48.660 回答
2

Boost::serialize 很棒

  • 支持不同版本的存档
  • 对大多数数据结构(指针、向量...)的良好支持
  • 非常快(1Gb 需要 10 秒,所以限制是您的硬盘)
  • 比较容易使用
  • 如果与 boost::iostreams 一起使用,则进行动态压缩

缺点是:

  • 存档可能不兼容从一个平台到另一个
  • 只针对C++,不与其他语言交流

一个正在增长的不错的替代方案是来自 Google http://code.google.com/p/protobuf/的协议缓冲区

  • 语言无关
  • 版本支持
  • 非常快

所以如果你想在不同系统之间交换数据,我会选择协议缓冲区。但是,如果您有一个应用程序,我会使用 boost::serialize

于 2011-02-25T12:41:59.293 回答