C#和.NET:如何使用BinaryWriter将结构序列化为byte 数组?

如何使用BinaryWriter将相当复杂的结构序列化为byte []数组?

更新:

  • 为此,必须使用[Serializable]属性修饰每个结构(和子结构?)。

  • 我不需要实现ISerializable接口,因为它旨在通过自己的序列化来控制对象。

从评论来看,OP的场景要求与应用程序/ .NET的未来版本具有很强的兼容性,在这种情况下,我总是建议使用BinaryFormatter – 它有许多“function”在版本之间不能很好地工作(当然不是在平台之间) 。

我建议看一下基于合同的序列化器; 我有偏见,但我倾向于protobuf-net(映射到Google的protobuf规范)。 最简单的方法是以这样的方式对类型进行属性,即库可以使它们轻松工作(尽管也可以在没有属性的情况下完成),例如:

  [ProtoContract] public class Customer { [ProtoMember(1)] public List Orders {get {....}} [ProtoMember(2)] public string Name {get;set;} ... etc } 

(如果你已经完成了任何XmlSerializer或DataContractSerializer工作,属性appoach非常熟悉 – 如果你不想添加protobuf-net特定属性,protobuf-net可以使用那些属性)

然后像:

 Customer cust = ... byte[] data; using(var ms = new MemoryStream()) { Serializer.Serialize(ms, cust); data = ms.ToArray(); } 

以这种方式生成的数据是独立于平台的,并且可以加载到任何匹配的合同上(它甚至不需要是Customer – 它可以是通过属性具有匹配布局的任何类型)。 实际上,在大多数情况下,它可以轻松加载到任何其他protobuf实现 – Java,C ++等。

使用BinaryFormatter将对象序列化为byte []。 BinaryWriter仅用于将字节写入流。

 MyObject obj = new MyObject(); byte[] bytes; IFormatter formatter = new BinaryFormatter(); using (MemoryStream stream = new MemoryStream()) { formatter.Serialize(stream, obj); bytes = stream.ToArray(); } 

代码段。

 public static byte[] XmlSerializeToByte(T value) where T : class { if (value == null) { throw new ArgumentNullException(); } XmlSerializer serializer = new XmlSerializer(typeof(T)); using (MemoryStream memoryStream = new MemoryStream()) { using (XmlWriter xmlWriter = XmlWriter.Create(memoryStream)) { serializer.Serialize(xmlWriter, value); return memoryStream.ToArray(); } } } public static T XmlDeserializeFromBytes (byte[] bytes) where T : class { if (bytes == null || bytes.Length == 0) { throw new InvalidOperationException(); } XmlSerializer serializer = new XmlSerializer(typeof(T)); using (MemoryStream memoryStream = new MemoryStream(bytes)) { using (XmlReader xmlReader = XmlReader.Create(memoryStream)) { return (T)serializer.Deserialize(xmlReader); } } } //Serialize Duck duck = new Duck() { Name = "Donald Duck" }; byte[] bytes = Test.XmlSerializeToByte(duck); //Deserialize var deDuck = Test.XmlDeserializeFromBytes(bytes); Console.WriteLine(deDuck.Name);