C#:DataContractSerializer和不同的流



我想使用DataContractSerializer,但我对其WriteObject方法中的Stream参数感到困惑——我发现我可以使用MemoryStreamXmlWriter。我想知道:

  • 流选择对序列化有何影响?它会影响对象的大小吗
  • 当使用MemoryStream时,我总是得到一个二进制对象吗

这些问题可能很基本,但我一直在谷歌上搜索,找不到明确的答案。谢谢

DataContractSerializer本质上是一个基于xml的序列化程序。如果传递一个Stream,它将构造一个封装流的XmlWriter(特别是XmlDictionaryWriter),然后核心序列化代码写入XmlWriter

流选择对序列化有何影响?它会影响对象的大小吗?

使用不同的Stream实例不会影响内部发生的事情,但是与传递XmlWriter相比,这里可能存在细微的差异,这取决于编码是什么。如果传递Stream,则DataContractSerializer使用UTF-8;但是如果你给它传递一个XmlWriter,你可以指定不同的编码。

使用MemoryStream时,是否总是得到一个二进制对象?

MemoryStreambyte[]的包装器,是的:一旦你调用了.ToArray(),你就只得到了二进制。然而,也是恰好是xml,这是二进制的。两者都可以。

如果您想要实际上是二进制的序列化(意思是:基本上是二进制序列化格式,而不是xml/json/csv/等),那么可以考虑像protobuf-net这样的东西。

正如Marc所说,如果您使用WriteObject的重载,它占用Stream,那么无论传入的Stream实例的类型如何,DataContractSerializer写入流的字节都将包括XML文档的UTF-8编码文本。如果实例是MemoryStream,则最终会得到一个内存中的字节数组(因为MemoryStream就是这样),但这些字节包含UTF-8编码的XML文本,通常不会将其描述为二进制表示。

如果你使用WriteObject的重载,它需要XmlWriter,那么你最终得到的完全取决于你的XmlWriter是什么类型,以及它是如何初始化的。就DataContractSerializer而言,它将以适当的模式调用XmlWriter的方法来描述表示对象状态的XMLInfoset。Infoset的编码方式取决于XmlWriter的实现。

如果你有专门的需求,并且特别受虐,你可以实现自己的自定义XmlWriter来进行任何类型的编码、压缩、加密,无论你喜欢什么。或者,您可以传递一个XmlTextWriter,它将为您提供Infoset的文本编码(类似于Stream重载),但具有更多用于控制字符编码和文本格式的选项。通常情况下,你会传递一个XmlDictionaryWriter,然后根据你创建它的方式,你有各种编码选项

这些选项包括WCF自己的XML Infosets二进制编码:以获得使用XmlDictionaryWriter.CreateBinaryWriter创建实例的信息。由于WCF团队投入了大量精力来设计一个高效的二进制表示,以满足WCF的性能目标,我想,如果您能够确保生成的序列化对象只需要通过.NET代码进行反序列化,那么您将很难想出一个更好的选项。如果您需要基于公共标准的二进制表示,您可以考虑XmlDictionaryWriterMTOM风格。

相关内容

  • 没有找到相关文章

最新更新