详解序列化与反序列化

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

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

.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方法序列化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
{
    /// <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/

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java 对象的序列化是将对象的状态转换为字节流,以便将其存储在文件中或通过网络进行传输。而反序列化则是将字节流重新转换为对象,以便在程序中重新使用。 对象的序列化主要涉及到两个接口,即 Serializable 和 Externalizable。Serializable 接口是 Java 标准序列化机制的简单版本,所有需要序列化的类都需要实现这个接口。而 Externalizable 接口则需要自己实现序列化反序列化的方法。 在进行对象序列化时,可以使用 ObjectOutputStream 类来实现。通过这个类的 writeObject() 方法,可以将对象写入到输出流中。而在进行反序列化时,可以使用 ObjectInputStream 类来实现。通过这个类的 readObject() 方法,可以将字节流重新转换为对象。 对象序列化的主要用途包括: 1. 对象的持久化:通过将对象序列化后存储在文件中,可以实现对象的持久化,当程序再次启动时,可以反序列化读取文件并重新获取对象的状态。 2. 对象的传输:通过将对象序列化后通过网络传输,可以实现在不同计算机之间的对象传递。 在进行对象序列化时,需要注意以下几点: 1. 需要被序列化的对象和其引用的对象,都需要实现 Serializable 接口。 2. 对于不希望被序列化的属性,可以使用 transient 关键字进行标记。 3. 如果序列化的是一个对象的成员变量,而不是整个对象,那么成员变量对应的类也需要实现 Serializable 接口。 总之,Java 对象序列化反序列化是一种非常有用的机制,它可以将对象的状态转换为字节流进行存储或传输,以便在需要时重新获取对象。通过使用序列化机制,我们可以实现对象的持久化和传输,使得编程更加灵活和便捷。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值