跨平台和语言的(反)序列化

15

我正在寻找一种最方便的方法来序列化一堆C++结构,这样序列化就可以在C++和Java(至少)以及32位/64位,大端/小端平台之间传输。 要序列化的结构只包含数据,即它们是纯数据对象,没有状态或行为。

我们的想法是将这些结构序列化成一个八位字节块,我们可以“通用地”存储在数据库中,并在以后读取出来。 这样可以避免每当结构发生更改时即改变数据库,也避免将每个数据成员分配到字段 - 也就是说,我们只想要一个表以二进制块的形式“通用地”持有所有内容。 这将减少开发人员的工作量,并且在结构发生更改时需要较少的更改。

我已经查看了boost.serialize,但认为没有办法使其与Java兼容。 同样,对于Java继承Serializable也是如此。

如果有一种方法可以从IDL文件开始完成它,那就最好不过了,因为我们已经有描述这些结构的IDL文件了。

提前致谢!


1
看看 http://msgpack.org/ 它是跨平台和多语言的。 - ont.rif
7个回答

9

我在这里偶然遇到了一个非常类似的问题。虽然六年后,这对你可能没有用了,但希望对其他人有所帮助。

有很多替代品,可惜没有明显的赢家(尽管可以认为JSON是明显的赢家)。即使Google也推出了多个竞争技术(显然都被内部使用):

不要忘记在其他答案中发布的替代品。以下是一些:

  • YAML: 使用缩进代替双引号,比 JSON 更易读,但可能不如 JSON 高效,特别是在数据变大时。
  • BSON (二进制 JSON)
  • MessagePack (另一种紧凑的 JSON)

有这么多变种,JSON 显然在简单性/便利性和跨平台访问方面是胜者。随着 JavaScript 的兴起,在过去几年中它变得更加流行。很多人可能会将其作为默认解决方案,而没有多想(这就是我最初的做法 :P)。

然而,如果大小成为问题,但您希望保持简单,并且不使用更高级的库,那么您可以使用 zlib(这就是我现在正在使用的方法)或其他跨平台算法来压缩 JSON(但这是另一个话题)。

为了加快C++中的JSON处理,您还可以使用RapidJSON

请注意,压缩可以节省空间和带宽,但会在性能方面付出代价。 - Marco Roy

7
我很惊讶Jon Skeet还没有介入这个问题 :-) Protocol Buffers基本上是为这种跨语言传递结构化数据的场景而设计的。
话虽如此,如果您按照您的建议使用数据库,您真的不应该使用像Oracle或SQL Server这样的全功能RDBMS,而应该使用轻量级键值存储,例如Berkeley DB或许多“云表”引擎之一。

7
如果我想要进行跨语言操作,我通常会建议使用JSON,因为它易于支持JavaScript,并且有大量的库可用,同时也易于阅读和修改(相比XML,我认为JSON更小,更快,更易于阅读)。从空间效率上来说,它不是最有效的格式,而像协议缓冲区或Thrift这样的更机器可读的格式则具有优势(Thrift可以从IDL生成,但它也适用于编码服务,因此可能比您想要的更重)。

2
我建议使用SQLite数据库保存数据。可以将结构体存储为SQLite表中的数据库行。
生成的数据库文件在许多不同平台上都是二进制兼容的,可以作为BLOB存储在您的主数据库中。我相信该文件的大小与具有相同数据的压缩XML文件相当,但在处理期间内存使用量将显著低于XML DOM。

2
你需要ASN.1!(有些人将其称为二进制 XML。)ASN.1非常紧凑,因此非常适合在两个系统之间传输数据。对于那些认为这从未被使用的人来说:多个互联网协议都是基于ASN.1模型进行数据序列化的!

不幸的是,Java或C ++中没有太多可用于支持ASN.1的库。几年前我曾经使用过它,但无法找到一个好的、免费或廉价的工具来支持C ++中的ASN.1。在Objective Systems,他们正在销售ASN.1 / XML解决方案,但价格非常昂贵。(即C ++和Java的ASN.1编译器!)至少要花费你一只手臂!(但然后你将拥有一个可以单手使用的工具...)


好的建议,但是在这个项目中任何昂贵的东西都不行。不过我会记住的 :) - fwg

1

为什么你没有选择XML呢?它完全符合你的需求。C++和Java都可以轻松实现。

此外,我怀疑你将所有东西都存储为数据库中的blob的想法,使用关系型数据库,因为这是数据库设计的目的,或者切换到一些面向对象的数据库,比如http://www.versant.com/en_US/products/objectdatabase,它支持Java和C++。


2
由于会产生大量开销,XML和其他可读性格式并不是一个真正的选择。目前,我们正在考虑在不到一天的时间内将1TB的原始数据存储到单个磁盘中。XML的显着开销意味着我们无法存储所需的大量原始数据。 - fwg

0

还有Avro。请参考this问题,比较Apache Thrift、Protocol Buffers、MES等。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接