一、什么是序列化与反序列化
序列化时将对象状态转换为可保持或传输的形式的过程。序列化的补集是反序列化,反序列化是将流转换为对象。两个过程一起保证能够存储和传输数据。
.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序列化反序列化
{
///
/// MainWindow.xaml 的交互逻辑
///
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方法序列化Json
DataContractJsonSerializer 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
{
///
/// MainWindow.xaml 的交互逻辑
///
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(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(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二进制序列化
{
///
/// MainWindow.xaml 的交互逻辑
///
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/