.NET Core 对象到字节数组的序列化和反序列化
.NET Core中利用MemoryStream和BinaryFormatter可以实现对象到字节数组的序列化和反序列化:
定义ObjectSerializer类,实现对象到字节数组的序列化和反序列化
using System.IO; using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters.Binary; namespace Assembly { public static class ObjectSerializer { /// <summary> /// 将一个object对象序列化,返回一个byte[] /// </summary> /// <param name="obj">能序列化的对象</param> /// <returns></returns> public static byte[] ObjectToBytes(object obj) { using (MemoryStream ms = new MemoryStream()) { IFormatter formatter = new BinaryFormatter(); formatter.Serialize(ms, obj); return ms.GetBuffer(); } } /// <summary> /// 将一个序列化后的byte[]数组还原 /// </summary> /// <param name="Bytes"></param> /// <returns></returns> public static object BytesToObject(byte[] Bytes) { using (MemoryStream ms = new MemoryStream(Bytes)) { IFormatter formatter = new BinaryFormatter(); return formatter.Deserialize(ms); } } } }
用BinaryFormatter做序列化和反序列化最大的一个问题是,序列化和反序列化的类型必须是标记为[Serializable]的,也就是SerializableAttribute特性,而且SerializableAttribute特性是无法被继承的,例如我们如果有个类People标记了[Serializable],如下所示:
using System; using System.Collections.Generic; using System.Text; namespace ConsoleApp2 { [Serializable] public class People { public string Name { get; set; } public int Age { get; set; } } }
由于People类标记了[Serializable],所以它可以被BinaryFormatter序列化和反序列化,但是假如现在还有个类Child继承People,Child类没有被标记为[Serializable],那么Child类是无法被BinaryFormatter序列化和反序列化的,因为如上所述SerializableAttribute特性是无法被继承的。
Child类如下所示:
using System; using System.Collections.Generic; using System.Text; namespace ConsoleApp2 { public class Child : People { } }
建立.NET Core控制台项目,在Main方法中运行如下代码:
class Program { static void Main(string[] args) { var people = new People() { Name = "王大锤", Age = 30 }; var data = ObjectSerializer.ObjectToBytes(people); people = ObjectSerializer.BytesToObject(data) as People; Console.WriteLine("Press any key to end..."); Console.ReadKey(); } }
可以看到People类可以被成功序列化和反序列化
将Main方法的代码改为如下,再运行:
class Program { static void Main(string[] args) { var child = new Child() { Name = "王大锤", Age = 30 }; var data = ObjectSerializer.ObjectToBytes(child); child = ObjectSerializer.BytesToObject(data) as Child; Console.WriteLine("Press any key to end..."); Console.ReadKey(); } }
可以看到代码在ObjectSerializer类的ObjectToBytes方法中抛出了异常,异常提示Child类没有被标记位[Serializable]