C# XmlSerializer 和 BinaryFormatter 之间有什么区别

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1154198/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 09:31:04  来源:igfitidea点击:

What are the differences between the XmlSerializer and BinaryFormatter

c#.netserializationxml-serializationbinary-serialization

提问by ahsteele

I spent a good portion of time last week working on serialization. During that time I found many examples utilizing either the BinaryFormatter or XmlSerializer. Unfortunately, what I did not find were any examples comprehensively detailing the differences between the two.

上周我花了很多时间进行序列化。在那段时间里,我发现了许多使用 BinaryFormatter 或 XmlSerializer 的示例。不幸的是,我没有找到任何全面详细说明两者差异的例子。

The genesis of my curiosity lies in why the BinaryFormatter is able to deserialize directly to an interface whilst the XmlSerializer is not. Jon Skeetin an answer to "casting to multiple (unknown types) at runtime" provides an example of direct binary serialization to an interface. Stan R.provided me with the means of accomplishing my goal using the XmlSerializer in his answer to "XML Object Deserialization to Interface."

我好奇的根源在于为什么 BinaryFormatter 能够直接反序列化到接口,而 XmlSerializer 则不能。Jon Skeet在对“在运行时转换为多个(未知类型)”的回答中提供了一个直接二进制序列化到接口的示例。Stan R.在他对“ XML Object Deserialization to Interface”的回答中为我提供了使用 XmlSerializer 实现我的目标的方法。

Beyond the obvious of the BinaryFormatter utilizes binary serialization whilst the XmlSerializer uses XML I'd like to more fully understand the fundamental differences. When to use one or the other and the pros and cons of each.

除了明显的 BinaryFormatter 使用二进制序列化,而 XmlSerializer 使用 XML 我想更全面地了解基本差异。何时使用一种或另一种以及每种的优缺点。

采纳答案by Dustin Hodges

The reason a binary formatter is able to deserialize directly to an interface type is because when an object is originally serialized to a binary stream metadata containing type and assembly information is stuck in with the object data. This means that when the binary formatter deserializes the object it knows its type, builds the correct object and you can then cast that to an interface type that object implements.

二进制格式化程序能够直接反序列化为接口类型的原因是因为当对象最初被序列化为包含类型和程序集信息的二进制流元数据时,对象数据会被卡住。这意味着当二进制格式化程序反序列化对象时,它知道它的类型,构建正确的对象,然后您可以将其转换为对象实现的接口类型。

The XML serializer on the otherhand just serializes to a schema and only serializes the public fields and values of the object and no type information other then that (e.g. interfaces the type implements).

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

Here is a good post, .NET Serialization, comparing the BinaryFormatter, SoapFormatter, and XmlSerializer. I recommend you look at the following table which in addition to the previously mentioned serializers includes the DataContractSerializer, NetDataContractSerializerand protobuf-net.

这是一篇好文章.NET Serialization,比较了BinaryFormatterSoapFormatterXmlSerializer。我建议您查看下表,除了前面提到的序列化程序外,还包括DataContractSerializerNetDataContractSerializerprotobuf-net

Serialization Comparison

序列化比较

回答by Rob Levine

The XmlSerializer serialises the type by reading all the type's properties that have both a public getter and a public setter (and also any public fields). In this sense the XmlSerializer serializes/deserializes the "public view" of the instance.

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

The binary formatter, by contrast, serializes a type by serializing the instance's "internals", i.e. its fields. Any fields that are not marked as [NonSerialized] will be serialized to the binary stream. The type itself must be marked as [Serializable] as must any internal fields that are also to be serialized.

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

回答by John Saunders

The XML Serializer produces XML and also an XML Schema (implicitly). It will produce XML that conforms to this schema.

XML Serializer 生成 XML 和 XML Schema(隐式)。它将生成符合此模式的 XML。

One implication is that it will not serialize anything which cannot be described in XML Schema. For instance, there is no way to distinguish between a list and an array in XML Schema, so the XML Schema produced by the serializer can be interpreted either way.

一种含义是它不会序列化任何不能在 XML Schema 中描述的东西。例如,在 XML Schema 中无法区分列表和数组,因此序列化器生成的 XML Schema 可以以任何一种方式解释。

Runtime serialization (which the BinaryFormatteris part of) serializes the actual .NET types to the other side, so if you send a List<int>, the other side will get a List<int>.

运行序列化(其BinaryFormatter是一部分)序列化的实际.NET类型到另一边,因此,如果您发送List<int>,对方会得到一个List<int>

That obviously works better if the other side is running .NET.

如果另一方运行 .NET,这显然效果更好。

回答by paradisontheitroad

I guess one of the most important ones is that binary serialization can serialize both public and private members, whereas the other one works only with public ones.

我想最重要的一个是二进制序列化可以序列化公共成员和私有成员,而另一个只适用于公共成员。

In here, it provides a very helpful comparison between these two in terms of size. It's a very important issue, because you might send your serialized object to a remote machine.

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

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

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

回答by Marc Gravell

Just to weigh in...

只是为了权衡...

The obvious difference between the two is "binary vs xml", but it does go a lot deeper than that:

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

  • fields (BinaryFormatter=bf) vs publicmembers (typically properties) (XmlSerializer=xs)
  • type-metadata based (bf) vs contract-based (xs)
  • version-brittle (bf) vs version-tolerant (xs)
  • "graph" (bf) vs "tree" (xs)
  • .NET specific (bf) vs portable (xs)
  • opaque (bf) vs human-readable (xs)
  • 字段(BinaryFormatter=bf)与公共成员(通常是属性)(XmlSerializer=xs)
  • 基于类型元数据 (bf) 与基于合约 (xs)
  • 版本脆弱(bf)与版本容忍(xs)
  • “图形”(bf)与“树”(xs)
  • .NET 特定 (bf) 与可移植 (xs)
  • 不透明 (bf) 与人类可读 (xs)

As a discussion of why BinaryFormattercan be brittle, see here.

关于为什么BinaryFormatter会变脆的讨论,请参见此处

It is impossible to discuss which is bigger; all the type metadata in BinaryFormattercan make it bigger. And XmlSerializercan work very with compression like gzip.

不可能讨论哪个更大;中的所有类型元数据都BinaryFormatter可以使它更大。并且XmlSerializer可以很好地处理像 gzip 这样的压缩。

However, it is possible to take the strengths of each; for example, Google have open-sourced their own data serialization format, "protocol buffers". This is:

但是,可以发挥每个人的优势;例如,谷歌已经开源了他们自己的数据序列化格式,“协议缓冲区”。这是:

  • contract-based
  • portable (see list of implementations)
  • version-tolerant
  • tree-based
  • opaque (although there are tools to show data when combined with a .proto)
  • typically "contract first", but some implementations allow implicit contracts based on reflection
  • 基于合同的
  • 便携(见实现列表
  • 版本容错
  • 基于树的
  • 不透明(虽然有一些工具可以在与 .proto 结合时显示数据)
  • 通常“契约优先”,但一些实现允许基于反射的隐式契约

But importantly, it is very dense data (no type metadata, pure binary representation, short tags, tricks like variant-length base-7 encoding), and very efficient to process (no complex xml structure, no strings to match to members, etc).

但重要的是,它是非常密集的数据(没有类型元数据、纯二进制表示、短标签、变长基 7 编码等技巧),并且处理非常高效(没有复杂的 xml 结构,没有与成员匹配的字符串等) )。

I might be a little biased; I maintain one of the implementations (including several suitable for C#/.NET), but you'll note I haven't linked to anyspecific implementation; the format stands under its own merits ;-p

我可能有点偏见;我维护了其中一种实现(包括几种适用于 C#/.NET 的实现),但您会注意到我没有链接到任何特定实现;格式有其自身的优点;-p