一起谈.NET技术,C#序列化与反序列化(Serializable and Deserialize)

简介:      序列化是指将对象实例的状态存储到存储媒体的过程。在此过程中,先将对象的公共字段和私有字段以及类的名称(包括类所在的程序集)转换为字节流,然后再把字节流写入数据流。在随后对对象进行反序列化时,将创建出与原对象完全相同的副本。

     序列化是指将对象实例的状态存储到存储媒体的过程。在此过程中,先将对象的公共字段和私有字段以及类的名称(包括类所在的程序集)转换为字节流,然后再把字节流写入数据流。在随后对对象进行反序列化时,将创建出与原对象完全相同的副本。

     我们经常需要将对象的字段值保存到磁盘中,并在以后检索此数据。尽管不使用序列化也能完成这项工作,但这种方法通常很繁琐而且容易出错,并且在需要跟踪对象的层次结构时,会变得越来越复杂。可以想象一下编写包含大量对象的大型业务应用程序的情形,程序员不得不为每一个对象编写代码,以便将字段和属性保存至磁盘以及从磁盘还原这些字段和属性。序列化提供了轻松实现这个目标的快捷方法。

     .NET公共语言运行时 (CLR) 管理对象在内存中的分布,.NET 框架则通过使用反射提供自动的序列化机制。对象序列化后,类的名称、程序集以及类实例的所有数据成员均被写入存储媒体中。对象通常用成员变量来存储对其他实例的引用。类序列化后,序列化引擎将跟踪所有已序列化的引用对象,以确保同一对象不被序列化多次。.NET 框架所提供的序列化体系结构可以自动正确处理对象图表和循环引用。对对象图表的唯一要求是,由正在进行序列化的对象所引用的所有对象都必须标记为 Serializable(请参阅基本序列化)。否则,当序列化程序试图序列化未标记的对象时将会出现异常。

当反序列化已序列化的类时,将重新创建该类,并自动还原所有数据成员的值。

     在C#中常见的序列化的方法主要也有三个:BinaryFormatter、SoapFormatter、XML序列化。本文就通过一个小例子主要说说这三种方法的具体使用和异同点。

新建一个vs2008控制台工程SerializableTest,添加一个Person类,加上[Serializable]使其可以被序列化

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SerializableTest
{
    [Serializable]
    public class Person
    {
        public string Sno { get; set; }
        public string Name { get; set; }
        public string Sex { get; set; }
        public int Age { get; set; }
        public string DisplayInfo()
        {
            return "我的学号是:" +Sno+ "\n我的名字是:"+Name + "\n我的性别为:"+Sex+"\n我的年龄:"+Age+"\n";
        }
    }
}

一、BinaryFormatter序列化方式

1、序列化:新建一个Person对象me,然后将其序列化保存到文件personInfo.txt中]

var me = new Person
                         {
                             Sno = "200719",
                             Name = "yuananyun",
                             Sex="man",
                             Age=22
                         };
            //创建一个格式化程序的实例
            IFormatter formatter = new BinaryFormatter();
            //创建一个文件流
            Stream stream = new FileStream("c:/personInfo.txt", FileMode.OpenOrCreate, FileAccess.Write, FileShare.None);
            formatter.Serialize(stream, me);
            stream.Close();

执行以上代码将创建一个personInfo.txt文件,它包含了me对象的程序集信息、类名和字段信息。

2、反序列化:从文件personInfo.txt中还原一个对象

 //反序列化
        Stream destream = new FileStream("c:/personInfo.txt", FileMode.Open,
            FileAccess.Read, FileShare.Read);
            var stillme = (Person)formatter.Deserialize(destream);
            stream.Close();

整个程序如下:

using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
namespace SerializableTest
{
    class Program
    {
        static void Main(string[] args)
        {
            //创建一个格式化程序的实例
            IFormatter formatter = new BinaryFormatter();
            Console.WriteLine("对象序列化开始……");
            var me = new Person
                         {
                             Sno = "200719",
                             Name = "yuananyun",
                             Sex="man",
                             Age=22
                         };
            //创建一个文件流
            Stream stream = new FileStream("c:/personInfo.txt", FileMode.OpenOrCreate, FileAccess.Write, FileShare.None);
            formatter.Serialize(stream, me);
            stream.Close();
            Console.WriteLine("序列化结束!\n");
            Console.WriteLine("反序列化开始……");
            //反序列化
            Stream destream = new FileStream("c:/personInfo.txt", FileMode.Open,
            FileAccess.Read, FileShare.Read);
            var stillme = (Person)formatter.Deserialize(destream);
            stream.Close();
            Console.WriteLine("反序列化结束,输出对象信息……");
            Console.WriteLine(stillme.DisplayInfo());
            Console.ReadKey();
        }
    }
}

运行结果如下:

 注意:反序列化还原对象时,并不会调用Person类的构造函数

二、SoapFormatter序列化方式

与BinaryFormatter序列化方式类似,只需要把IFormatter formatter = new BinaryFormatter()改成 IFormatter formatter = new SoapFormatter(),并且引用程序集System.Runtime.Serialization.Formatters.Soap.dll(.net自带的)

using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Soap;
namespace SerializableTest
{
    class Program
    {
        static void Main(string[] args)
        {
            //创建一个格式化程序的实例
            IFormatter formatter = new SoapFormatter();
            Console.WriteLine("对象序列化开始……");
            var me = new Person
                         {
                             Sno = "200719",
                             Name = "yuananyun",
                             Sex="man",
                             Age=22
                         };
            //创建一个文件流
            Stream stream = new FileStream("c:/personInfo.txt", FileMode.OpenOrCreate, FileAccess.Write, FileShare.None);
            formatter.Serialize(stream, me);
            stream.Close();
            Console.WriteLine("序列化结束!\n");
            Console.WriteLine("反序列化开始……");
            //反序列化
            Stream destream = new FileStream("c:/personInfo.txt", FileMode.Open,
            FileAccess.Read, FileShare.Read);
            var stillme = (Person)formatter.Deserialize(destream);
            stream.Close();
            Console.WriteLine("反序列化结束,输出对象信息……");
            Console.WriteLine(stillme.DisplayInfo());
            Console.ReadKey();
        }
    }
}

结果与第一种方式一样。

序列化之后的文件是Soap格式的文件(简单对象访问协议(Simple Object Access Protocol,SOAP),是一种轻量的、简单的、基于XML的协议,它被设计成在WEB上交换结构化的和固化的信息。 SOAP 可以和现存的许多因特网协议和格式结合使用,包括超文本传输协议(HTTP),简单邮件传输协议(SMTP),多用途网际邮件扩充协议(MIME)。它还支持从消息系统到远程过程调用(RPC)等大量的应用程序。SOAP使用基于XML的数据结构和超文本传输协议(HTTP)的组合定义了一个标准的方法来使用Internet上各种不同操作环境中的分布式对象。),其内容如下:

<SOAP-ENV:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:clr="http://schemas.microsoft.com/soap/encoding/clr/1.0" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<a1:Person id="ref-1" xmlns:a1="http://schemas.microsoft.com/clr/nsassem/SerializableTest/SerializableTest%2C%20Version%3D1.0.0.0%2C%20Culture%3Dneutral%2C%20PublicKeyToken%3Dnull">
<_x003C_Sno_x003E_k__BackingField id="ref-3">200719</_x003C_Sno_x003E_k__BackingField>
<_x003C_Name_x003E_k__BackingField id="ref-4">yuananyun</_x003C_Name_x003E_k__BackingField>
<_x003C_Sex_x003E_k__BackingField id="ref-5">man</_x003C_Sex_x003E_k__BackingField>
<_x003C_Age_x003E_k__BackingField>22</_x003C_Age_x003E_k__BackingField>
</a1:Person>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

三、XML序列化方式

using System;
using System.IO;
using System.Runtime.Serialization;
using System.Xml.Serialization;
namespace SerializableTest
{
    class Program
    {
        static void Main(string[] args)
        {
            //创建一个格式化程序的实例
            XmlSerializer formatter = new XmlSerializer(typeof(Person));
            Console.WriteLine("对象序列化开始……");
            var me = new Person
                         {
                             Sno = "200719",
                             Name = "yuananyun",
                             Sex="man",
                             Age=22
                         };
            //创建一个文件流
            Stream stream = new FileStream("c:/personInfo.txt", FileMode.OpenOrCreate, FileAccess.Write, FileShare.None);
            formatter.Serialize(stream, me);
            stream.Close();
            Console.WriteLine("序列化结束!\n");
            Console.WriteLine("反序列化开始……");
            //反序列化
            Stream destream = new FileStream("c:/personInfo.txt", FileMode.Open,
            FileAccess.Read, FileShare.Read);
            var stillme = (Person)formatter.Deserialize(destream);
            stream.Close();
            Console.WriteLine("反序列化结束,输出对象信息……");
            Console.WriteLine(stillme.DisplayInfo());
            Console.ReadKey();
        }
    }
}

结果与上述相同,xml序列化之后的文件就是一般的一个xml文件,personInfo.txt内容如下:

<?xml version="1.0"?>
<Person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Sno>200719</Sno>
  <Name>yuananyun</Name>
  <Sex>man</Sex>
  <Age>22</Age>
</Person>

注意:采用xml序列化的方式只能保存public的字段和可读写的属性,对于private等类型的字段不能进行序列化

下面进行验证

将Person的Name属性改成Private,然后查看生成的personInfo.text,其内容如下:

<?xml version="1.0"?>
<Person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Sno>200719</Sno>
  <Sex>man</Sex>
  <Age>22</Age>
</Person>

可以看到Name属性并没有出现在该文件中,反序列化生成的对象中Name属性值为NULL。

以上对c#序列化和反序列化的三种方式进行了举例说明。当然您也可以决定一个类中那些属性序列化或不序列化,可以通过使用 NonSerialized 属性标记成员变量来防止它们被序列化,具体内容请查阅相关资料。

目录
相关文章
|
11天前
|
机器学习/深度学习 人工智能 Cloud Native
洞察.NET 技术的前沿应用
【7月更文挑战第4天】**洞察.NET技术前沿:.NET Core跨平台崛起,云原生与AI应用深化。ML.NET、TensorFlow.NET助力机器学习,Xamarin与MAUI统一跨平台UI。Azure云服务支持下,.NET引领软件开发新趋势。**
23 5
|
11天前
|
人工智能 物联网 开发工具
.NET技术:多元语言、丰富库与跨平台能力引领软件开发新纪元。
`【7月更文挑战第4天】.NET技术:多元语言、丰富库与跨平台能力引领软件开发新纪元。从企业应用、云服务到游戏开发,其角色日益凸显。随着微软的持续创新与社区合作,未来.NET将在物联网、AI等领域拓宽应用,开发者应把握趋势,共创未来。`
13 0
|
11天前
|
人工智能 开发框架 Devops
.NET技术概览:** 本文探讨了.NET的核心特性,包括多语言支持、Common Language Runtime、丰富的类库和跨平台能力,强调其在企业级、Web、移动及游戏开发中的应用。
【7月更文挑战第4天】.NET技术概览:** 本文探讨了.NET的核心特性,包括多语言支持、Common Language Runtime、丰富的类库和跨平台能力,强调其在企业级、Web、移动及游戏开发中的应用。此外,讨论了.NET如何通过性能优化、DevOps集成、AI与ML支持以及开源策略应对未来挑战,为开发者提供强大工具,共创软件开发新篇章。
20 3
|
11天前
|
人工智能 前端开发 开发工具
**.NET技术概览:** 本文探讨.NET的核心优势
【7月更文挑战第4天】**.NET技术概览:** 本文探讨了.NET的核心优势,如统一开发平台、Visual Studio的强大工具、跨平台能力及丰富的类库。它在现代应用中的创新应用包括企业级、Web、移动、云服务和游戏开发。同时,面对性能优化、容器化、AI集成等挑战,.NET正寻求未来机遇,通过开源社区持续发展。开发者应抓住这些趋势,利用.NET推动软件创新。
20 1
|
11天前
|
人工智能 前端开发 Devops
NET技术在现代开发中的影响力日益增强,本文聚焦其核心价值,如多语言支持、强大的Visual Studio工具、丰富的类库和跨平台能力。
【7月更文挑战第4天】**.NET技术在现代开发中的影响力日益增强,本文聚焦其核心价值,如多语言支持、强大的Visual Studio工具、丰富的类库和跨平台能力。实际应用涵盖企业系统、Web、移动和游戏开发,以及云服务。面对性能挑战、容器化、AI集成及跨平台竞争,.NET持续创新,开发者应关注技术趋势,提升技能,并参与社区,共同推进技术发展。**
12 1
|
11天前
|
机器学习/深度学习 人工智能 开发者
.NET 技术:为开发带来新机遇
【7月更文挑战第4天】**.NET技术开启软件开发新篇章,通过跨平台革命(.NET Core, Xamarin, .NET MAUI)、云服务与微服务(Azure, DevOps, Docker)及AI集成(ML.NET, 认知服务, TensorFlow)为开发者创造新机遇。开源社区的繁荣与性能提升使.NET更具竞争力,推动智能应用的创新与发展。开发者需紧跟潮流,利用这些工具和框架构建高效、创新的解决方案。**
8 1
|
9天前
|
人工智能 开发框架 调度
C#/.NET这些实用的技巧和知识点你都知道吗?
C#/.NET这些实用的技巧和知识点你都知道吗?
|
11天前
|
人工智能 前端开发 开发工具
.NET技术探析:优势、创新应用及挑战。
【7月更文挑战第4天】**.NET技术探析:优势、创新应用及挑战。本文分三部分展开,阐述了.NET作为统一多语言开发平台的核心优势,如强大的Visual Studio工具、跨平台能力与丰富的类库;探讨了其在企业级、Web、移动及游戏开发中的创新角色;并指出面临性能优化、容器化、AI集成等挑战及未来开源社区驱动的发展机遇。通过理解与应对,开发者可借助.NET推动软件开发进步。**
14 0
|
17天前
|
开发框架 .NET Nacos
使用 Nacos 在 C# (.NET Core) 应用程序中实现高效配置管理和服务发现
使用 Nacos 在 C# (.NET Core) 应用程序中实现高效配置管理和服务发现
40 0
|
18天前
|
XML 机器学习/深度学习 移动开发
技术笔记:log4net使用详解
技术笔记:log4net使用详解
17 0