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

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

.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 属性标记成员变量来防止它们被序列化,具体内容请查阅相关资料。

转载于:https://www.cnblogs.com/waw/archive/2011/09/01/2162747.html

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

  1. c语言 ipc 参数 序列化,浅谈IPC通信之序列化与反序列化(三)

    由于进行通信肯定要涉及数据的处理,所以我们需要先了解两个基础的概念,序列化和反序列化. 定义 序列化:将对象转化为可保存的字节序列(注意是对象): 反序列:将字节序列恢复为对象的过程. 序列化和反序列 ...

  2. 浅谈C#中的序列化和反序列化

    一.序列化和反序列化的概念 序列化:序列化是将对象转换为可保持或传输的格式的过程,比如转化为二进制.xml.json等的过程. 反序列化:与序列化相对的是反序列化,它将流转换为对象,也就是将在序列化过 ...

  3. [Java]LeetCode297. 二叉树的序列化与反序列化 | Serialize and Deserialize Binary Tree

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ ➤微信公众号:山青咏芝(shanqingyongzhi) ➤博客园地址:山青咏芝(https://www.cnblog ...

  4. PHP序列化及反序列化绕过

    序列化和反序列化及绕过 前言 序列化和反序列化 序列化 反序列化 反序列化绕过 序列化利用 ctf题目实例 攻防世界 unserialize3 攻防世界 Web_php_unserialize ctf ...

  5. 一起谈.NET技术,ASP.NET 中JSON 的序列化和反序列化

    JSON是专门为浏览器中的网页上运行的JavaScript代码而设计的一种数据格式.在网站应用中使用JSON的场景越来越多,本文介绍ASP.NET中JSON的序列化和反序列化,主要对JSON的简单介绍 ...

  6. 序列化和反序列化(转载美团网技术团队)

    摘要 序列化和反序列化几乎是工程师们每天都要面对的事情,但是要精确掌握这两个概念并不容易:一方面,它们往往作为框架的一部分出现而湮没在框架之中:另一方面,它们会以其他更容易理解的概念出现,例如加密.持 ...

  7. 第四节:IO、序列化和反序列化、加密解密技术

    一. IO读写 这里主要包括文件的读.写.移动.复制.删除.文件夹的创建.文件夹的删除等常规操作. 注意:这里需要特别注意,对于普通的控制台程序和Web程序,将"相对路径"转换成& ...

  8. ios序列化与反序列化,本地化

    2019独角兽企业重金招聘Python工程师标准>>> 你是用什么方法来持久保存数据的?这是在几乎每一次关于iOS技术的交流或讨论都会被提到的问题,而且大家对这个问题的热情持续高涨. ...

  9. K:java中的序列化与反序列化

    Java序列化与反序列化是什么?为什么需要序列化与反序列化?如何实现Java序列化与反序列化?以下内容将围绕这些问题进行展开讨论. Java序列化与反序列化 简单来说Java序列化是指把Java对象转 ...

最新文章

  1. 经管资源库项目的总结笔记
  2. 每日一皮:据说现在小孩从小容易生病、体质不如从前是因为少了这个运动......
  3. 合成未来宝宝照片_[萌主争霸]2020年台历宝宝投票评选开始啦!快来给你喜欢的萌宝投票吧~...
  4. 对话罗伟:5G背景下 物联网领域最大挑战在于商业模式
  5. Resharper进阶一:简要介绍
  6. RTP/RTCP协议与RTSP协议
  7. KubeSphere配置应用路由
  8. Sublime Text4添加配色主题
  9. 老漏洞easy击:CVE-2012 0158占顶!
  10. Spring Framework 4.0 M1: WebSocket 支持
  11. 合肥青少年信息学计算机竞赛试题,合肥市第二十九届青少年信息学奥林匹克竞赛(小学组)试题及部分答案...
  12. from表单的重置按钮(reset)不能重置隐藏input框的值
  13. java 二进制加减_二进制加法Java实现
  14. androidStudio中通过svn版本控制后整个工作空间代码变成红色或者绿色
  15. 我为国内微积分“小糊涂”感到悲哀!
  16. 72名图灵奖获得者的成就
  17. Nvidia jetson tx2 ubuntu16.04插入128GB内存卡报错:Unable to access/mount “128 GB Volume”
  18. 新手玩转unwallet攻略
  19. 宜人贷蜂巢ELK Stack之elasticsearch权限探索
  20. 李开复自传里的一些话

热门文章

  1. hdu 5036 Explosion bitset优化floyd
  2. css--左右visibility建立 “collapse”值问题
  3. 你是否觉得.Net Web Service 中asmx文件是多余的?
  4. C#中使用OpenGL(API)创建OpenGL渲染环境
  5. Qt中的模态对话框和非模态对话框
  6. MFC中创建和使用线程的方法
  7. c++中scanf和printf
  8. ap drawing 课件_ILITEK TP AP introduction.ppt
  9. java url gbk编码转换_如何在一个utf-8编码的HTML中 在javascript中url跳转时把url中的汉字改为GBK编码...
  10. oracle游标循环定义变量赋值,PL/SQL  循环 数组 游标的使用