序列化字节数组与XML文件

我大量使用字节数组来传输对象,原始数据,通过网络和返回。 我通过一个类型实现ISerializable来适应java的方法,它包含两个方法,作为接口的一部分,ReadObjectData和WriteObjectData。 任何使用此接口的类都会将日期写入字节数组。 像那样的东西

class SerializationType:ISerializable { void ReadObjectData (/*Type that manages the write/reads into the byte array*/){} void WriteObjectData(/*Type that manages the write/reads into the byte array*/){} } 

写完所有对象后,我发送一个网络数组。


这实际上是双重问题。 它是通过网络以最高效率(速度,大小)发送数据的正确方法吗?

您是否会使用此方法将对象写入文件,而不是通常使用xml序列化?

编辑#1

Joel Coehoorn提到了BinaryFormatter。 我从未使用过这门课。 除了我目前在msdn上看到的内容之外,你会详细说明,提供好的例子,参考资料,建议,当前的做法吗?

这应该没问题,但你正在做已经完成的工作。 查看System.Runtime.Serialization.Formatters.Binary.BinaryFormatter类。

不需要为每种特定类型实现自己的Read / WriteOjbectData()方法,您只需使用已经可以处理大多数任何对象的类。 它基本上采用几乎任何.Net对象的内存表示的精确副本,并将其写入流中或从流中读取它:

 BinaryFormatter bf = new BinaryFormatter(); bf.Serialize(outputStream, objectToSerialize); objectToDeserialize = bf.Deserialize(inputStream) as DeserializedType; 

确保阅读链接文档:unicode字符串可能存在问题,并且确切的内存表示并不总是合适的(例如,打开套接字等)。

如果您正在进行简单,轻量级和高效的二进制序列化,请考虑使用protobuf-net ; 基于谷歌的协议缓冲区格式,但从头开始实现典型的.NET使用。 特别是,它既可以单独使用(通过protobuf-net的Serializer ),也可以通过实现ISerializable (并委托给Serializer )通过BinaryFormatter使用。

除了高效之外,这种格式设计为可扩展和可移植(即与java / php / C ++“协议缓冲区”实现兼容),不像BinaryFormatter,它既是特定于实现又是版本不容忍的。 这意味着你不必乱写任何序列化代码……

当框架中已有一个接口时,创建自己的ISerializable接口听起来像是一个灾难的配方。 至少给它一个不同的名字。

在阅读时你会遇到一些问题 – 你将没有一个实例来调用该方法。 您可能希望将其变为某种“工厂”:

 public interface ISerializationFactory { T ReadObjectData(Stream input); void WriteObjectData(Stream output); } 

至于XML与二进制……它完全取决于具体情况:有多少数据,你需要向后兼容,.NET中的XML序列化是否已经给你足够的控制权等等。

是的,这比发送XML要快,因为你将通过网络发送更少的数据。 即使您压缩XML(这将大大减小其大小),您仍然会有压缩和解压缩的开销。 所以我想说在你目前正在做的事情和XML序列化之间,你目前正在使用最有效的解决方案。

但是我很好奇你使用XML而不是封送对象会导致多少性能损失。 我鼓励您研究XML序列化的原因是因为您将以一种人类可读的应用程序中立格式存储数据。 如果您能够以不会对应用程序造成性能损失的方式将数据序列化为XML,我建议您进行调查。

关于写入文件,通常您希望将对象序列化为XML,如果您希望能够读取序列化或者可能更改它。 如果您不希望序列化是人类可读的,那么您也可以重用二进制序列化。

如果您确实希望它是人类可读的,那么需要考虑XML,但这取决于您需要序列化的数据类型。 XML本质上是递归的,因此适用于序列化同样的递归数据。 它不太适合其他类型的数据。

换句话说,选择适合您需求的持久序列化。 这里没有单向适合的解决方案。

至于网络,通常你会希望将大小保持在最低限度,因此XML通常不会是一个很好的选择,因为它的冗长。

序列化(在Java中)看似简单。 只要你做简单的事情(比如从不改变课程)就很容易 – 但是它也有很多“有趣”的东西。

有关Java序列化的详细讨论请参阅Effective Java (特别是第10章)。

对于C#,不确定,但核心问题可能是相同的。

这里有一个关于C#序列化的例子: http : //www.codeproject.com/KB/cs/objserial.aspx 。

XStream库提供了一种处理序列化的非常好的方法,包括支持XML,JSON和支持自定义转换器。 具体来说,使用自定义转换器可以减少XML冗长并严格序列化所需的内容。

XStream没有要求将所有内容声明为Serializable,这在使用第三方库并且需要从该lib序列化类的实例时非常重要,该lib未声明为Serializable。


答案已经被接受,但为了完整性的讨论,这里有一个链接,可以很好地比较不同的序列化方法/库:

http://code.google.com/p/thrift-protobuf-compare/wiki/Benchmarking

kryo库看起来非常引人注目的Java序列化。 与XStream类似,它支持自定义转换器。