C# 序列化与反序列化
序列化是把一个内存中的对象的信息转化成一个可以持久化保存的形式,以便于保存或传输,序列化的主要作用是不同平台之间进行通信,常用的有序列化有json、xml、文件等,下面就逐个讲下这三种序列化的方法。
一、序列化为json
C#中用于对象和json相互转换的原生类有两个:DataContractJsonSerializer和JavaScriptSerializer,其中JavaScriptSerializer主要用于web的浏览器和服务器之间的通信。这里主要讲DataContractJsonSerializer的使用,要使用DataContractJsonSerializer,先要在项目中引用System.Runtime.Serialization。首先准备一个测试的类Book:
1 [DataContract] 2 class Book 3 { 4 [DataMember] 5 public int ID { get; set; } 6 7 [DataMember] 8 public string Name { get; set; } 9 10 [DataMember] 11 public float Price { get; set; } 12 }
[DataContract]指定该类型要定义或实现一个数据协定,并可由序列化程序(如 System.Runtime.Serialization.DataContractSerializer)进行序列化。
[DataMember]当应用于类型的成员时,指定该成员是数据协定的一部分并可由 System.Runtime.Serialization.DataContractSerializer进行序列化。
然后先创建一个Book对象,实例化一个DataContractJsonSerializer实例,最后用该实例的WriteObject()方法将对象写到流中,代码如下:
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 Book book = new Book() { ID = 101, Name = "C#程序设计", Price = 79.5f }; 6 7 //序列化json 8 DataContractJsonSerializer formatter= new DataContractJsonSerializer(typeof(Book)); 9 using (MemoryStream stream = new MemoryStream()) 10 { 11 formatter.WriteObject(stream, book); 12 string result = System.Text.Encoding.UTF8.GetString(stream.ToArray()); 13 Console.WriteLine(result); 14 } 15 } 16 }
程序的输出结果如图:
将一个json格式的字符串反序列化为对象是用DataContractJsonSerializer实例的ReadObject()方法,代码如下:
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 Book book = new Book() { ID = 101, Name = "C#程序设计", Price = 79.5f };15 6 //反序列化json 7 string oriStr = "{\"ID\":101,\"Name\":\"C#程序设计\",\"Price\":79.5}"; 8 DataContractJsonSerializer formatter = new DataContractJsonSerializer(typeof(Book)); 9 using (MemoryStream stream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(oriStr))) 10 { 11 Book outBook = formatter.ReadObject(stream) as Book; 12 Console.WriteLine(outBook.ID); 13 Console.WriteLine(outBook.Name); 14 Console.WriteLine(outBook.Price); 15 } 16 Console.Read(); 17 } 18 }
程序输出结果如图:
我们也可以把上面的json序列化与反序列为封装成泛型方法,这样可以公用,全部代码如下:
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 Book book = new Book() { ID = 101, Name = "C#程序设计", Price = 79.5f }; 6 7 //序列化json 8 string result = Serializer.ObjectToJson<Book>(book); 9 Console.WriteLine(result); 10 11 //反序列化json 12 string oriStr = "{\"ID\":101,\"Name\":\"C#程序设计\",\"Price\":79.5}"; 13 Book outBook = Serializer.JsonToObject<Book>(oriStr); 14 Console.WriteLine(outBook.ID); 15 Console.WriteLine(outBook.Name); 16 Console.WriteLine(outBook.Price); 17 18 Console.Read(); 19 } 20 } 21 22 public class Serializer 23 { 24 /// 将对象序列化为json文件 25 /// </summary> 26 /// <typeparam name="T">类型</typeparam> 27 /// <param name="t">实例</param> 28 /// <param name="path">存放路径</param> 29 public static void ObjectToJson<T>(T t, string path) where T : class 30 { 31 DataContractJsonSerializer formatter = new DataContractJsonSerializer(typeof(T)); 32 using (FileStream stream = new FileStream(path, FileMode.OpenOrCreate)) 33 { 34 formatter.WriteObject(stream, t); 35 } 36 } 37 38 /// <summary> 39 /// 将对象序列化为json字符串 40 /// </summary> 41 /// <typeparam name="T">类型</typeparam> 42 /// <param name="t">实例</param> 43 /// <returns>json字符串</returns> 44 public static string ObjectToJson<T>(T t) where T : class 45 { 46 DataContractJsonSerializer formatter = new DataContractJsonSerializer(typeof(T)); 47 using (MemoryStream stream = new MemoryStream()) 48 { 49 formatter.WriteObject(stream, t); 50 string result = System.Text.Encoding.UTF8.GetString(stream.ToArray()); 51 return result; 52 } 53 } 54 55 /// <summary> 56 /// json字符串转成对象 57 /// </summary> 58 /// <typeparam name="T">类型</typeparam> 59 /// <param name="json">json格式字符串</param> 60 /// <returns>对象</returns> 61 public static T JsonToObject<T>(string json) where T : class 62 { 63 DataContractJsonSerializer formatter = new DataContractJsonSerializer(typeof(Book)); 64 using (MemoryStream stream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(json))) 65 { 66 T result = formatter.ReadObject(stream) as T; 67 return result; 68 } 69 } 70 }
二、序列化为xml
C#中将对象序列化和反序列化为xml的类是XmlSerializer,要引用System.Xml.Serialization
先创建一个XmlSerializer对象实例,然后用实例的Serialize的方法将对象写入到文件流中,代码如下:
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 Book book = new Book() { ID = 101, Name = "C#程序设计", Price = 79.5f }; 6 7 XmlSerializer formatter = new XmlSerializer(typeof(Book)); 8 using (FileStream stream = new FileStream(@"c:\book.xml", FileMode.OpenOrCreate)) 9 { 10 formatter.Serialize(stream, book); 11 } 12 Console.Read(); 13 } 14 }
程序运行后会在c盘产生一个book.xml文件,内容如下:
当然也可以将对象转换成对象流,然后转换成xml格式的字符串,代码和效果图如下:
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 Book book = new Book() { ID = 101, Name = "C#程序设计", Price = 79.5f }; 6 7 XmlSerializer formatter = new XmlSerializer(typeof(Book)); 8 using (MemoryStream stream = new MemoryStream()) 9 { 10 formatter.Serialize(stream, book); 11 string result = System.Text.Encoding.UTF8.GetString(stream.ToArray());//转换成xml字符串 12 Console.WriteLine(result); 13 } 14 Console.Read(); 15 } 16 }
将xml文件反序列化的方法是用XmlSerializer实例的Deserialize()方法,代码如下:
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 Book book = new Book() { ID = 101, Name = "C#程序设计", Price = 79.5f }; 6 7 XmlSerializer formatter = new XmlSerializer(typeof(Book)); 8 using (FileStream stream = new FileStream(@"c:book.xml", FileMode.OpenOrCreate)) 9 { 10 XmlReader xmlReader = new XmlTextReader(stream); 11 Book outBook = formatter.Deserialize(xmlReader) as Book;//反序列化 12 Console.WriteLine(outBook.ID); 13 Console.WriteLine(outBook.Name); 14 Console.WriteLine(outBook.Price); 15 } 16 Console.Read(); 17 } 18 }
程序执行完成效果如图:
我们同样也可以把上面的xml序列化与反序列为封装成泛型方法,这样可以公用,全部代码如下:
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 Book book = new Book() { ID = 101, Name = "C#程序设计", Price = 79.5f }; 6 7 //序列化xml 8 Serializer.ObjectToXml(book, @"c:\book.xml"); 9 10 //反序列化xml 11 Book outBook = Serializer.XmlToObject(book, @"c:\book.xml"); 12 Console.WriteLine(outBook.ID); 13 Console.WriteLine(outBook.Name); 14 Console.WriteLine(outBook.Price); 15 Console.Read(); 16 } 17 } 18 19 public class Serializer 20 { 21 /// <summary> 22 /// 将对象序列化为xml文件 23 /// </summary> 24 /// <typeparam name="T">类型</typeparam> 25 /// <param name="t">对象</param> 26 /// <param name="path">xml存放路径</param> 27 public static void ObjectToXml<T>(T t,string path) where T : class 28 { 29 XmlSerializer formatter = new XmlSerializer(typeof(T)); 30 using (FileStream stream = new FileStream(path, FileMode.OpenOrCreate)) 31 { 32 formatter.Serialize(stream, t); 33 } 34 } 35 36 /// <summary> 37 /// 将对象序列化为xml字符串 38 /// </summary> 39 /// <typeparam name="T">类型</typeparam> 40 /// <param name="t">对象</param> 41 public static string ObjectToXml<T>(T t) where T : class 42 { 43 XmlSerializer formatter = new XmlSerializer(typeof(T)); 44 using (MemoryStream stream = new MemoryStream()) 45 { 46 formatter.Serialize(stream, t); 47 string result = System.Text.Encoding.UTF8.GetString(stream.ToArray()); 48 return result; 49 } 50 } 51 52 /// <summary> 53 /// 将xml文件反序列化为对象 54 /// </summary> 55 /// <typeparam name="T">类型</typeparam> 56 /// <param name="t">对象</param> 57 /// <param name="path">xml路径</param> 58 /// <returns>对象</returns> 59 public static T XmlToObject<T>(T t, string path) where T : class 60 { 61 XmlSerializer formatter = new XmlSerializer(typeof(T)); 62 using (FileStream stream = new FileStream(path, FileMode.OpenOrCreate)) 63 { 64 XmlReader xmlReader = new XmlTextReader(stream); 65 T result = formatter.Deserialize(xmlReader) as T; 66 return result; 67 } 68 } 69 }
三、序列化为文件
C#中将对象序列化和反序列化为二进制文件的类是BinaryFormatter,要引用System.Runtime.Serialization.Formatters.Binary
先创建一个BinaryFormatter对象实例,然后用实例的Serialize的方法将对象写入到文件流中,代码如下:
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 Book book = new Book() { ID = 101, Name = "C#程序设计", Price = 79.5f }; 6 7 //序列化文件 8 BinaryFormatter formatter = new BinaryFormatter(); 9 using (FileStream stream = new FileStream(@"c:\book.txt", FileMode.OpenOrCreate)) 10 { 11 formatter.Serialize(stream, book); 12 } 13 Console.Read(); 14 } 15 }
程序执行完成后产生bool.txt文件,如图:
可以通过BinaryFormatter类型实例的Deserialize()方法把二进制文本反序列化为对象,代码如下:
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 Book book = new Book() { ID = 101, Name = "C#程序设计", Price = 79.5f }; 6 7 //序列化文件 8 BinaryFormatter formatter = new BinaryFormatter(); 9 using (FileStream stream = new FileStream(@"c:\book.txt", FileMode.OpenOrCreate)) 10 { 11 Book outBook = formatter.Deserialize(stream) as Book; 12 Console.WriteLine(outBook.ID); 13 Console.WriteLine(outBook.Name); 14 Console.WriteLine(outBook.Price); 15 } 16 Console.Read(); 17 } 18 }
程序执行后显示如图:
我们同样也可以把序列化和把序列化为二进制文件的方法封装成泛型方法,全部代码如下:
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 Book book = new Book() { ID = 101, Name = "C#程序设计", Price = 79.5f }; 6 //序列化文件 7 Serializer.ObjectToFile(book, @"c:\book.txt"); 8 9 //反序列化文件 10 Book outBook = Serializer.FileToObject<Book>(@"c:\book.txt") as Book; 11 Console.WriteLine(outBook.ID); 12 Console.WriteLine(outBook.Name); 13 Console.WriteLine(outBook.Price); 14 Console.Read(); 15 } 16 } 17 18 public class Serializer 19 { 20 #region 文件序列化 21 /// <summary> 22 /// 将对象序列化为字符串 23 /// </summary> 24 /// <typeparam name="T">类型</typeparam> 25 /// <param name="t">实例</param> 26 /// <returns>字符串</returns> 27 public static string ObjectToString<T>(T t) 28 { 29 BinaryFormatter formatter = new BinaryFormatter(); 30 using (MemoryStream stream = new MemoryStream()) 31 { 32 formatter.Serialize(stream, t); 33 string result = System.Text.Encoding.UTF8.GetString(stream.ToArray()); 34 return result; 35 } 36 } 37 38 /// <summary> 39 /// 将对象序列化为文件 40 /// </summary> 41 /// <typeparam name="T">类型</typeparam> 42 /// <param name="t">实例</param> 43 /// <param name="path">存放路径</param> 44 public static void ObjectToFile<T>(T t, string path) 45 { 46 BinaryFormatter formatter = new BinaryFormatter(); 47 using (FileStream stream = new FileStream(path, FileMode.OpenOrCreate)) 48 { 49 formatter.Serialize(stream, t); 50 stream.Flush(); 51 } 52 } 53 54 /// <summary> 55 /// 将字符串反序列为类型 56 /// </summary> 57 /// <typeparam name="T">类型</typeparam> 58 /// <param name="s">字符串</param> 59 /// <returns>对象</returns> 60 public static T StringToObject<T>(string s) where T : class 61 { 62 byte[] buffer = System.Text.Encoding.UTF8.GetBytes(s); 63 BinaryFormatter formatter = new BinaryFormatter(); 64 using (MemoryStream stream = new MemoryStream(buffer)) 65 { 66 T result = formatter.Deserialize(stream) as T; 67 return result; 68 } 69 } 70 71 /// <summary> 72 /// 将文件反序列化为对象 73 /// </summary> 74 /// <typeparam name="T">类型</typeparam> 75 /// <param name="path">路径</param> 76 /// <returns>对象</returns> 77 public static T FileToObject<T>(string path) where T : class 78 { 79 using (FileStream stream = new FileStream(path, FileMode.Open)) 80 { 81 BinaryFormatter formatter = new BinaryFormatter(); 82 T result = formatter.Deserialize(stream) as T; 83 return result; 84 } 85 } 86 #endregion 87 } 88 89 [Serializable] 90 public class Book 91 { 92 public int ID { get; set; } 93 public string Name { get; set; } 94 public float Price { get; set; } 95 }