详解序列化与反序列化

一、什么是序列化与反序列化

序列化时将对象状态转换为可保持或传输的形式的过程。序列化的补集是反序列化,反序列化是将流转换为对象。两个过程一起保证能够存储和传输数据。

.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/

你可能感兴趣的:(C#,c#)