本笔记摘抄自:https://www.cnblogs.com/maitian-lf/p/3670570.html,记录一下学习过程以备后续查用。
序列化是把一个内存中的对象的信息转化成一个可以持久化保存的形式,以便于保存或传输。序列化的主要作用是不同平台之间进行通信,常用的序
列化有json、xml、文件等,下面就逐个讲下这三种序列化的方法。
一、序列化为json
C#中用于对象和json相互转换的原生类有两个:DataContractJsonSerializer和JavaScriptSerializer,其中JavaScriptSerializer主要用于web浏览器和服
务器之间的通信。这里主要讲DataContractJsonSerializer的使用,要使用DataContractJsonSerializer,先要在项目中引用System.Runtime.Serialization。
首先准备一个测试的类Book:
class Program { /// <summary> /// Book类 /// </summary> [DataContract] class Book { [DataMember] public int ID { get; set; } [DataMember] public string Name { get; set; } [DataMember] public float Price { get; set; } } static void Main(string[] args) { } }
[DataContract]指定该类型要定义或实现一个数据协定,并可由序列化程序(如System.Runtime.Serialization.DataContractSerializer)进行序列化。
[DataMember]当应用于类型的成员时,指定该成员是数据协定的一部分并可由System.Runtime.Serialization.DataContractSerializer进行序列化。
首先创建一个Book对象,然后实例化一个DataContractJsonSerializer实例,最后用该实例的WriteObject()方法将对象写到流中,代码如下:
class Program { /// <summary> /// Book类 /// </summary> [DataContract] class Book { [DataMember] public int Id { get; set; } [DataMember] public string Name { get; set; } [DataMember] public float Price { get; set; } } static void Main(string[] args) { #region 对象序列化为json Book book = new Book() { Id = 101, Name = "C#程序设计", Price = 79.5f }; //序列化为json DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(Book)); using (MemoryStream stream = new MemoryStream()) { jsonSerializer.WriteObject(stream, book); string result = Encoding.UTF8.GetString(stream.ToArray()); Console.WriteLine(result); } Console.Read(); #endregion } }
运行结果如下:
将一个json格式的字符串反序列化为对象是用DataContractJsonSerializer实例的ReadObject()方法,代码如下:
class Program { /// <summary> /// Book类 /// </summary> [DataContract] class Book { [DataMember] public int Id { get; set; } [DataMember] public string Name { get; set; } [DataMember] public float Price { get; set; } } static void Main(string[] args) { #region json反序列化为对象 Book book = new Book(); //json反序列化为对象 string oriStr = "{\"Id\":101,\"Name\":\"C#程序设计\",\"Price\":79.5}"; DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(Book)); using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(oriStr))) { Book outBook = jsonSerializer.ReadObject(stream) as Book; Console.WriteLine($"{outBook.Id} {outBook.Name} {outBook.Price}"); } Console.Read(); #endregion } }
运行结果如下:
我们也可以把上面的json序列化与反序列为封装成泛型方法,这样可以公用,全部代码如下:
class Program { /// <summary> /// Book类 /// </summary> [DataContract] class Book { [DataMember] public int Id { get; set; } [DataMember] public string Name { get; set; } [DataMember] public float Price { get; set; } } public class SerializerHelper { /// 将对象序列化为json文件 /// </summary> /// <typeparam name="T">类型</typeparam> /// <param name="t">实例</param> /// <param name="path">存放路径</param> public static void ObjectToJson<T>(T t, string path) where T : class { DataContractJsonSerializer formatter = new DataContractJsonSerializer(typeof(T)); using (FileStream stream = new FileStream(path, FileMode.OpenOrCreate)) { formatter.WriteObject(stream, t); } } /// <summary> /// 将对象序列化为json字符串 /// </summary> /// <typeparam name="T">类型</typeparam> /// <param name="t">实例</param> /// <returns>json字符串</returns> public static string ObjectToJson<T>(T t) where T : class { DataContractJsonSerializer formatter = new DataContractJsonSerializer(typeof(T)); using (MemoryStream stream = new MemoryStream()) { formatter.WriteObject(stream, t); string result = Encoding.UTF8.GetString(stream.ToArray()); return result; } } /// <summary> /// 将json字符串反序列化为对象 /// </summary> /// <typeparam name="T">类型</typeparam> /// <param name="json">json格式字符串</param> /// <returns>对象</returns> public static T JsonToObject<T>(string json) where T : class { DataContractJsonSerializer formatter = new DataContractJsonSerializer(typeof(T)); using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(json))) { T result = formatter.ReadObject(stream) as T; return result; } } } static void Main(string[] args) { #region json序列化与反序列化泛型方法 Book book = new Book() { Id = 101, Name = "C#程序设计", Price = 79.5f }; //对象序列化为json string result = SerializerHelper.ObjectToJson(book); Console.WriteLine(result); //json反序列化为对象 string oriStr = "{\"Id\":101,\"Name\":\"C#程序设计\",\"Price\":79.5}"; Book outBook = SerializerHelper.JsonToObject<Book>(oriStr); Console.WriteLine($"{outBook.Id} {outBook.Name} {outBook.Price}"); Console.Read(); #endregion } }
运行结果如下:
二、序列化为xml
C#中将对象序列化和反序列化为xml的类是XmlSerializer,要引用System.Xml.Serialization。
首先创建一个XmlSerializer对象实例,然后用实例的Serialize方法将对象写入到文件流中,代码如下:
public class Program { /// <summary> /// Book类 /// </summary> [DataContract] public class Book { [DataMember] public int Id { get; set; } [DataMember] public string Name { get; set; } [DataMember] public float Price { get; set; } } static void Main(string[] args) { #region 对象序列化为xml(文件流) Book book = new Book() { Id = 101, Name = "C#程序设计", Price = 79.5f }; XmlSerializer xmlSerializer = new XmlSerializer(typeof(Book)); using (FileStream stream = new FileStream(@"E:\book.xml", FileMode.OpenOrCreate)) { xmlSerializer.Serialize(stream, book); } Console.Read(); #endregion } }
程序运行后会在c盘产生一个book.xml文件,内容如下:
<?xml version="1.0"?> <Book xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <Id>101</Id> <Name>C#程序设计</Name> <Price>79.5</Price> </Book>
当然也可以将对象转换成对象流,然后转换成xml格式的字符串,代码如下:
运行结果如下:
将xml文件反序列化的方法是用XmlSerializer实例的Deserialize()方法,代码如下:
public class Program { /// <summary> /// Book类 /// </summary> [DataContract] public class Book { [DataMember] public int Id { get; set; } [DataMember] public string Name { get; set; } [DataMember] public float Price { get; set; } } static void Main(string[] args) { #region xml文件反序列化为对象 Book book = new Book() { Id = 101, Name = "C#程序设计", Price = 79.5f }; XmlSerializer xmlSerializer = new XmlSerializer(typeof(Book)); using (FileStream stream = new FileStream(@"E:\book.xml", FileMode.OpenOrCreate)) { XmlReader xmlReader = new XmlTextReader(stream); Book outBook = xmlSerializer.Deserialize(xmlReader) as Book;//反序列化 Console.WriteLine($"{outBook.Id} {outBook.Name} {outBook.Price}"); } Console.Read(); #endregion } }
运行结果如下:
我们同样也可以把上面的xml序列化与反序列为封装成泛型方法,这样可以公用,全部代码如下:
public class Program { /// <summary> /// Book类 /// </summary> [DataContract] public class Book { [DataMember] public int Id { get; set; } [DataMember] public string Name { get; set; } [DataMember] public float Price { get; set; } } /// <summary> /// 序列化反序列化帮助类 /// </summary> public class SerializerHelper { /// <summary> /// 将对象序列化为xml文件 /// </summary> /// <typeparam name="T">类型</typeparam> /// <param name="t">对象</param> /// <param name="path">xml存放路径</param> public static void ObjectToXml<T>(T t, string path) where T : class { XmlSerializer formatter = new XmlSerializer(typeof(T)); using (FileStream stream = new FileStream(path, FileMode.OpenOrCreate)) { formatter.Serialize(stream, t); } } /// <summary> /// 将对象序列化为xml字符串 /// </summary> /// <typeparam name="T">类型</typeparam> /// <param name="t">对象</param> public static string ObjectToXml<T>(T t) where T : class { XmlSerializer formatter = new XmlSerializer(typeof(T)); using (MemoryStream stream = new MemoryStream()) { formatter.Serialize(stream, t); string result = Encoding.UTF8.GetString(stream.ToArray()); return result; } } /// <summary> /// 将xml文件反序列化为对象 /// </summary> /// <typeparam name="T">类型</typeparam> /// <param name="t">对象</param> /// <param name="path">xml路径</param> /// <returns>对象</returns> public static T XmlToObject<T>(T t, string path) where T : class { XmlSerializer formatter = new XmlSerializer(typeof(T)); using (FileStream stream = new FileStream(path, FileMode.OpenOrCreate)) { XmlReader xmlReader = new XmlTextReader(stream); T result = formatter.Deserialize(xmlReader) as T; return result; } } } static void Main(string[] args) { #region xml序列化与反序列化泛型方法 Book book = new Book() { Id = 101, Name = "C#程序设计", Price = 79.5f }; //对象序列化为xml SerializerHelper.ObjectToXml(book, @"E:\book.xml"); //xml反序列化为对象 Book outBook = SerializerHelper.XmlToObject(book, @"E:\book.xml"); Console.WriteLine($"{outBook.Id} {outBook.Name} {outBook.Price}"); Console.Read(); #endregion } }
三、序列化为二进制文件
C#中将对象序列化和反序列化为二进制文件的类是BinaryFormatter,要引用System.Runtime.Serialization.Formatters.Binary,另外Book类头要加
[Serializable]属性。
先创建一个BinaryFormatter对象实例,然后用实例的Serialize的方法将对象写入到文件流中,代码如下:
public class Program { /// <summary> /// Book类 /// </summary> [DataContract] [Serializable] public class Book { [DataMember] public int Id { get; set; } [DataMember] public string Name { get; set; } [DataMember] public float Price { get; set; } } static void Main(string[] args) { #region 对象序列化为二进制文件 Book book = new Book() { Id = 101, Name = "C#程序设计", Price = 79.5f }; //对象序列化为二进制文件 BinaryFormatter formatter = new BinaryFormatter(); using (FileStream stream = new FileStream(@"E:\book.txt", FileMode.OpenOrCreate)) { formatter.Serialize(stream, book); } Console.Read(); #endregion } }
可以通过BinaryFormatter类型实例的Deserialize()方法把二进制文本反序列化为对象,代码如下:
public class Program { /// <summary> /// Book类 /// </summary> [DataContract] [Serializable] public class Book { [DataMember] public int Id { get; set; } [DataMember] public string Name { get; set; } [DataMember] public float Price { get; set; } } static void Main(string[] args) { #region 将二进制文件反序列化为对象 Book book = new Book() { Id = 101, Name = "C#程序设计", Price = 79.5f }; //序列化文件 BinaryFormatter formatter = new BinaryFormatter(); using (FileStream stream = new FileStream(@"E:\book.txt", FileMode.OpenOrCreate)) { Book outBook = formatter.Deserialize(stream) as Book; Console.WriteLine($"{outBook.Id} {outBook.Name} {outBook.Price}"); } Console.Read(); #endregion } }
运行结果如下:
我们同样也可以把序列化和把序列化为二进制文件的方法封装成泛型方法,全部代码如下:
public class Program { /// <summary> /// Book类 /// </summary> [DataContract] [Serializable] public class Book { [DataMember] public int Id { get; set; } [DataMember] public string Name { get; set; } [DataMember] public float Price { get; set; } } /// <summary> /// 序列化反序列化帮助类 /// </summary> public class SerializerHelper { #region 二进制文件序列化反序列化 /// <summary> /// 将对象序列化为字符串 /// </summary> /// <typeparam name="T">类型</typeparam> /// <param name="t">实例</param> /// <returns>字符串</returns> public static string ObjectToString<T>(T t) { BinaryFormatter formatter = new BinaryFormatter(); using (MemoryStream stream = new MemoryStream()) { formatter.Serialize(stream, t); string result = Encoding.UTF8.GetString(stream.ToArray()); return result; } } /// <summary> /// 将对象序列化为二进制文件 /// </summary> /// <typeparam name="T">类型</typeparam> /// <param name="t">实例</param> /// <param name="path">存放路径</param> public static void ObjectToBinaryFile<T>(T t, string path) { BinaryFormatter formatter = new BinaryFormatter(); using (FileStream stream = new FileStream(path, FileMode.OpenOrCreate)) { formatter.Serialize(stream, t); stream.Flush(); } } /// <summary> /// 将字符串反序列为对象 /// </summary> /// <typeparam name="T">类型</typeparam> /// <param name="s">字符串</param> /// <returns>对象</returns> public static T StringToObject<T>(string s) where T : class { byte[] buffer = Encoding.UTF8.GetBytes(s); BinaryFormatter formatter = new BinaryFormatter(); using (MemoryStream stream = new MemoryStream(buffer)) { T result = formatter.Deserialize(stream) as T; return result; } } /// <summary> /// 将二进制文件反序列化为对象 /// </summary> /// <typeparam name="T">类型</typeparam> /// <param name="path">路径</param> /// <returns>对象</returns> public static T BinaryFileToObject<T>(string path) where T : class { using (FileStream stream = new FileStream(path, FileMode.Open)) { BinaryFormatter formatter = new BinaryFormatter(); T result = formatter.Deserialize(stream) as T; return result; } } #endregion } static void Main(string[] args) { #region 二进制文件序列化反序列化泛型方法 Book book = new Book() { Id = 101, Name = "C#程序设计", Price = 79.5f }; //对象序列化为二进制文件 SerializerHelper.ObjectToBinaryFile(book, @"E:\book.txt"); //二进制文件反序列化为对象 Book outBook = SerializerHelper.BinaryFileToObject<Book>(@"E:\book.txt") as Book; Console.WriteLine($"{outBook.Id} {outBook.Name} {outBook.Price}"); Console.Read(); #endregion } }
运行结果如下: