XmlSerializer 和 BinaryFormatter 之间有什么区别
-
18-09-2019 - |
题
上周我花了很大一部分时间进行连载。在那段时间里,我发现了许多使用 BinaryFormatter 或 XmlSerializer 的示例。不幸的是,我没有找到任何全面详细说明两者之间差异的例子。
我好奇的根源在于为什么 BinaryFormatter 能够直接反序列化到接口,而 XmlSerializer 却不能。 乔恩·斯基特 在回答“在运行时转换为多个(未知类型)” 提供了一个直接二进制序列化到接口的示例。 斯坦·R。 在他对“的回答”中,为我提供了使用 XmlSerializer 实现目标的方法XML 对象反序列化为接口."
除了 BinaryFormatter 使用二进制序列化而 XmlSerializer 使用 XML 之外,我想更全面地了解根本差异。何时使用其中一种以及每种的优缺点。
解决方案
二进制格式化程序能够直接反序列化为接口类型的原因是,当对象最初序列化为二进制流时,包含类型和程序集信息的元数据会与对象数据粘在一起。这意味着当二进制格式化程序反序列化对象时,它知道其类型,构建正确的对象,然后您可以将其转换为对象实现的接口类型。
另一方面,XML 序列化程序仅序列化为模式,并且仅序列化对象的公共字段和值,除此之外没有任何类型信息(例如类型实现的接口)。
这里有一个好帖子, .NET 序列化, ,比较 二进制格式化程序, 肥皂格式化程序, , 和 Xml序列化器. 。我建议您查看下表,除了前面提到的序列化器之外,还包括 数据契约序列化器, NetDataContractSerializer 和 protobuf网络.
其他提示
只是为了衡量在...
显而易见的两者之间的差异是"二元vs xml",但它确实去了很多比这更深:
- 领域(
BinaryFormatter
=bf)与 公共 成员(一般性)(XmlSerializer
=x) - 类型的元数据基(bf)与基于合同(x)
- 版脆(bf)与版本的宽容(x)
- "图"(bf)与"树"(x)
- .净具体(bf)与便携式(x)
- 不透明的(bf)与人可读(x)
作为一个讨论为什么 BinaryFormatter
可以脆弱, 看看这里.
这是不可能的讨论,这是更大;所有类型的元数据 BinaryFormatter
可以使它更大。和 XmlSerializer
可工作很有压缩像gzip。
然而,这是可能采取的优势;例如,谷歌公开来源的自己的数据序列化格式,"议定书的缓冲区".这是:
但重要的是,它是非常密集的数据(没有类型的元数据,纯的二进制代表性,短标签、技巧喜欢变长基-7的编码),并且非常有效的处理(不复杂的xml结构,没有任何匹配的成员,等等)。
我可能有点偏见;我保持一个实现(包括若干适用于C#/.净额),但你注意到我没有 链接到 任何 具体执行;该格式的代表在自己的案情;-p
在XML序列产生XML并且还一个XML Schema(隐式地)。它将产生的XML符合该模式。
一个含义是,它不会序列不能在XML模式来描述任何东西。例如,没有办法的列表和在XML模式的阵列之间进行区分,所以由串行器产生的XML模式可以被解释两种方式。
运行序列化(其中BinaryFormatter
是的一部分)串行化的实际.NET类型到另一侧,因此,如果您发送List<int>
,在另一侧将得到List<int>
。
这明显更好地工作,如果另一侧运行.NET。
在XmlSerializer的通过读取同时具有公共的吸气和一个公共设置器(以及任何公共字段)的所有类型的串行化性质的类型。在这个意义上的XmlSerializer序列化/反序列化实例的“公共视图”。
在二进制格式化,相比之下,通过串行化实例的“内部”,即,其场串行化一个类型。未标记为[非序列化]的任何字段将被序列到二进制流。类型本身必须被标记为[序列化]作为必须被序列化的任何内部字段也
我想最重要的问题之一是,二进制序列化可以序列化的公共和私有成员,而另一个与公立才起作用。
在这里,它提供了在大小方面这两者之间一个非常有用的比较。这是一个非常重要的问题,因为你可能把你的序列化对象到远程计算机。
HTTP: //www.nablasoft.com/alkampfer/index.php/2008/10/31/binary-versus-xml-serialization-size/