一、什么是序列化与反序列化
序列化时将对象状态转换为可保持或传输的形式的过程。序列化的补集是反序列化,反序列化是将流转换为对象。两个过程一起保证能够存储和传输数据。
.NET具有以下三种序列化技术:
1.二进制序列化 保持类型保真,这对于多次调用应用程序时保持对象状态非常有用。例如,通过将对象序列化到粘贴板,可在不同的应用程序之间共享对象。您可以将对象序列化到流,磁盘,内存和网络等。远程处理使用序列化,“按值”在计算机或应用程序域之间传递对象。
2.XML和SOAP序列化,之序列化公共属性和字段,并且保持类型保真。当您希望提供或使用数据而不限制使用数据的应用程序时,这一点非常有用。由于XML是开放式的标准,因此它对于通过Web共享数据来说是一个理想选择。SOAP同样是开放式的标准,这使它成为一个理想选择。
3.JSON序列化,之序列化公共属性,并且不保持类型保真。JSON是开放式的标准,对于通过Web共享数据来说是一个理想选择
现在的序列化工具有三种:
1).DataCo
ntractJsonSerializer
要在项目中添加引用 System.Runtime.Serialization 还需要添加引用 System.ServiceModel.Web
在Student类中我们要引用
System.Runtime.Serialization;
using System.Runtime.Serialization;namespace _04序列化反序列化
{[DataContract]//指定该类型要定义或实现一个数据协定,并可由序列化程序public class Student{[DataMember]public string Name { get; set; }[DataMember]public int Sex { get; set; }[DataMember]public int Age { get; set; }[DataMember]public Address Address { get; set; }}[DataContract]public class Address{[DataMember]public string City { get; set; }[DataMember]public string Road { get; set; }}
}
在代码中处理Student对象时要引用
using System.Runtime.Serialization.Json;
using System.IO;
using System.Runtime.Serialization.Json;
using System.Text;
using System.Windows;namespace _04序列化反序列化
{/// <summary>/// MainWindow.xaml 的交互逻辑/// </summary>public partial class MainWindow : Window{public MainWindow(){InitializeComponent();Student student = new Student{Name = "Tom",Age = 18,Sex = 1,Address = new Address{City = "BeiJing",Road = "ChaoYangRoad"}};//利用WirteObject方法序列化JsonDataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(Student));MemoryStream stream = new MemoryStream();serializer.WriteObject(stream, student);byte[] bytes = new byte[stream.Length];stream.Position = 0;stream.Read(bytes, 0, (int)stream.Length);string jsonStr = Encoding.UTF8.GetString(bytes);//反序列化stream = new MemoryStream(Encoding.Default.GetBytes(jsonStr));Student student0 = (Student)serializer.ReadObject(stream);}}
}
2).JavaScriptSerializer
使用JavaScriptSerializer,将前面定义的类中的DataContract和DataMember都去掉。使用JavaScriptSerializer只需要引用的命名空间System.Web.Script.Serialization;
代码如下:
Student对象为
namespace _05JavaScriptSerializer
{public class Student{public string Name { get; set; }public int Sex { get; set; }public int Age { get; set; }public Address Address { get; set; }}public class Address{public string City { get; set; }public string Road { get; set; }}
}
using System.Web.Script.Serialization;
利用JavaScriptSerializer对象进行序列化和反序列化的代码如下:
using System.Web.Script.Serialization;
using System.Windows;namespace _05JavaScriptSerializer
{/// <summary>/// MainWindow.xaml 的交互逻辑/// </summary>public partial class MainWindow : Window{public MainWindow(){InitializeComponent();Student student = new Student{Name = "Tom",Age = 18,Sex = 1,Address = new Address{City = "BeiJing",Road = "ChaoYangRoad"}};JavaScriptSerializer serializer = new JavaScriptSerializer();string jsonStr = serializer.Serialize(student);//序列化完成//反序列化Student student1 = serializer.Deserialize<Student>(jsonStr);}}
}
3).Newtonsoft.Json
Newtonsoft.Json 功能有很多,除了序列化反序列化之外,还有 Linq To Json、Json Path、 XML support等,我们这篇文章我们只讲解其中的序列化和反序列化。使用 Newtonsoft.Json 前首先我们需要在 nuget 中搜索并安装,安装完成后引入 Newtonsoft.Json,代码如下
using Newtonsoft.Json;
Student student = new Student{Name = "Tom",Age = 20,Sex = 1,Address = new Address{City = "NYC",Road = "ABC"}};//序列化string jsonStr = JsonConvert.SerializeObject(student);//反序列化Student student1 = JsonConvert.DeserializeObject<Student>(jsonStr);
2. XML 在 JSON 还没出现之前,XML 是互联网上常用的数据交换格式和规范。.NET 中提供 XmlSerializer 类将对象序列化为 XML 和将 XML 反序列化为对象,使用方法是首先实例化,然后调用序列化/反序列化方法。下面我们依然使用最开始定义的那个类,来看看 XmlSerializer 的使用。使用前我们需要引入 using System.Xml.Serialization 命名空间。
using System.Xml.Serialization;
//XML序列化XmlSerializer xmlSerializer = new XmlSerializer(typeof(Student));using (FileStream stream = new FileStream(@"d:\summer.xml", FileMode.OpenOrCreate)){xmlSerializer.Serialize(stream, student);}//XML反序列化using (FileStream stream1=new FileStream(@"d:\summer.xml",FileMode.OpenOrCreate)){XmlReader xmlReader = new XmlTextReader(stream1);Student student2 = xmlSerializer.Deserialize(xmlReader) as Student;}
3. 二进制 序列化为二进制,在实际开发中真的很少用到,但是我觉得还是有必要讲一讲,它的使用方法和 XmlSerializer 序列化/反序列化类似,首先实例化,然后调用序列化/反序列化方法。在进行序列化/反序列化前首先引入命名空间 System.Runtime.Serialization.Formatters.Binary ,同时修改对象类如下
using System;namespace _07二进制序列化
{public class Class1{//如果注释掉 此标记,则提示 System.Runtime.Serialization.SerializationException://“程序集“07二进制序列化, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null”中的类型“_07二进制序列化.Class1+Student”//未标记为可序列化。”[Serializable]public class Student{public string Name { get; set; }public int Sex { get; set; }public int Age { get; set; }public Address Address { get; set; }}[Serializable]public class Address{public string City { get; set; }public string Road { get; set; }}}
}
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Windows;
using static _07二进制序列化.Class1;namespace _07二进制序列化
{/// <summary>/// MainWindow.xaml 的交互逻辑/// </summary>public partial class MainWindow : Window{public MainWindow(){InitializeComponent();#region 序列化Student student = new Student{Name = "Tom",Age = 20,Sex = 1,Address = new Address{City = "NYC",Road = "ABC"}};BinaryFormatter binFormat = new BinaryFormatter();string fileName = System.IO.Path.Combine(@"D:\", @"321.bin");using (Stream fStream = new FileStream(fileName, FileMode.Create, FileAccess.ReadWrite)){binFormat.Serialize(fStream, student);}#endregion#region 反序列化using (Stream fStream = new FileStream(fileName, FileMode.Open, FileAccess.ReadWrite)){fStream.Position = 0;student = (Student)binFormat.Deserialize(fStream);}#endregion}}
}
备注:如果想具体详细的了解序列化与反序列化,可以参考官方文档
demo例子上述列子https://download.csdn.net/download/m0_58717895/76176989
官方文档https://docs.microsoft.com/zh-cn/dotnet/standard/serialization/