XmlSerializer和BinaryFormatter有什么区别

上周我花了很长时间来研究系列化。 在那段时间里,我发现很多使用BinaryFormatter或者XmlSerializer的例子。 不幸的是,我没有find全面详细说明两者之间差异的例子。

我的好奇心的起源在于为什么BinaryFormatter能够直接反序列化到一个接口,而XmlSerializer没有。 Jon Skeet在“ 在运行时转换为多个(未知types) ”的答案中提供了一个直接二进制序列化到接口的例子。 Stan R.在“ XML Object Deserialization to Interface ”的回答中为我提供了使用XmlSerializer完成目标的方法。

除了BinaryFormatter的显而易见的利用二进制序列化,而XmlSerializer使用XML我想更充分地了解的基本差异。 什么时候使用其中一种或每种使用的利弊。

二进制格式化程序能够直接反序列化到接口types的原因是,当一个对象最初被序列化为二进制stream时,元数据包含types和程序集信息与对象数据卡在一起。 这意味着当二进制格式化程序对它知道它的types的对象进行反序列化时,就构build了正确的对象,然后你可以将它转换为对象实现的接口types。

另一方面,XML序列化器只是序列化为一个模式,并且只序列化对象的公共字段和值,除此之外没有任何types信息(例如接口types实现)。

这是一个很好的post, .NET序列化 ,比较BinaryFormatter , SoapFormatter和XmlSerializer 。 我build议你看看下面的表格,除了前面提到的序列化器,还包括DataContractSerializer , NetDataContractSerializer和protobuf-net 。

序列化比较

只是为了权衡…

两者之间的明显区别是“二进制与xml”,但是它比这个更深入:

  • 字段( BinaryFormatter = bf)vs 公共成员(通常属性)( XmlSerializer = xs)
  • 基于types元数据(bf)与基于合同(xs)
  • 版本脆弱(bf)vs版本容忍(xs)
  • “图”(bf)与“树”(xs)
  • 特定于.NET(bf)与便携式(xs)
  • 不透明(bf)与人可读(xs)

有关BinaryFormatter为什么会变得脆弱的讨论, 请看这里 。

讨论哪个更大是不可能的; BinaryFormatter所有types元数据可以使其变大。 和XmlSerializer可以像gzip压缩一样工作。

但是,可以采取每个的优势。 例如,Google已经开源了自己的数据序列化格式“协议缓冲区”。 这是:

  • 合同为基础
  • 便携式(请参阅实施列表 )
  • 版本容错
  • 基于树
  • 不透明的(虽然有一些工具可以显示与.proto结合的数据)
  • 通常是“ 合同第一 ”,但是一些实现允许基于reflection的隐式合同

但重要的是,它是非常密集的数据(没有types元数据,纯二进制表示,短标签,变异长度的base-7编码等技巧),并且处理效率非常高(没有复杂的xml结构,没有与成员匹配的string等)。

我可能会有点偏见; 我维护其中一个实现(包括几个适合C#/ .NET),但是你会注意到我没有链接到任何具体的实现; 该格式是根据其自身的优点; – p

XML序列化程序产生XML,也是一个XML模式(隐式地)。 它将产生符合这个模式的XML。

其中一个含义是,它不会序列化XML Schema中无法描述的任何内容。 例如,在XML Schema中没有办法区分列表和数组,因此序列化程序产生的XML Schema可以被解释。

运行时序列化( BinaryFormatter是其中的一部分)将实际的.NETtypes序列化到另一端,所以如果发送List<int> ,另一端将得到一个List<int>

如果对方运行.NET,那显然会更好。

XmlSerializer通过读取具有公共getter和public setter(以及任何公共字段)的所有types的属性来串行化types。 在这个意义上,XmlSerializer序列化/反序列化实例的“公共视图”。

相比之下,二进制格式化程序通过序列化实例的“内部”(即其内部字段)来序列化types。 任何未标记为[NonSerialized]的字段将被序列化为二进制stream。 types本身必须标记为[可序列化],因为必须序列化的任何内部字段。

我猜其中最重要的一个是二进制序列化可以序列化公共和私人成员,而另一个只能与公共成员序列化。

在这里,它提供了这两个在大小方面非常有用的比较。 这是一个非常重要的问题,因为您可能会将您的序列化对象发送到远程机器。

http://www.nablasoft.com/alkampfer/index.php/2008/10/31/binary-versus-xml-serialization-size/