C#三十一 序列化与反序列化

序列化又称串行化,是.NET运行时环境用来支持用户定义类型的流化的机制。其目的是以某种存储形成使自定义对象持久化,或者将这种对象从一个地方传输到另一个地方。

.NET框架提供了两种串行化的方式:1、是使用BinaryFormatter进行串行化;2、使用SoapFormatter进行串行化;3、使用XmlSerializer进行串行化。第一种方式提供了一个简单的二进制数据流以及某些附加的类型信息,而第二种将数据流格式化为XML存储;第三种其实和第二种差不多也是XML的格式存储,只不过比第二种的XML格式要简化很多(去掉了SOAP特有的额外信息)。

可以使用[Serializable]属性将类标志为可序列化的。如果某个类的元素不想被序列化,1、2可以使用[NonSerialized]属性来标志,2、可以使用[XmlIgnore]来标志。

重点:

?      理解序列化 / 反序列化概念

?      能够使用序列化/反序列化保持和恢复对象状态

预习功课:

?      序列化的概念

?      反序列化的概念

?      如何使用序列化和反序列化保持和恢复对象状态

?      如何利用序列化来操作Xml文件

8.1 序列化和反序列化简介

C#序列化和反序列化,两者的程序处理方式基本一致,都是基于工厂模式的,所谓C#序列化就是是将对象转换为容易传输的格式的过程,一般情况下转化打流文件,放入内存或者IO文件中。例如,可以序列化一个对象,然后使用 HTTP 通过 Internet 在客户端和服务器之间传输该对象,或者和其它应用程序共享使用。相反的,反序列化根据流重新构造对象。.NET自带的有两种序列化对象的方式,Xml和binary的,XML 序列化不转换方法、索引器、私有字段或只读属性(只读集合除外)。要序列化对象的所有字段和属性(公共的和私有的),请使用
BinaryFormatter,而不要使用 XML 序列化。

8.1.1 C#序列化和反序列化的实例应用剖析:

二进制的C#序列化的方式:

例如我们有个对象:

1.            [Serializable]public class ClassToSerialize{

2.            public int id=100;

3.            public string name="Name";

4.            }

需要序列化该对象,必须在给该类加上Serializable的属性,然后创建一个序列化写入的流:FileStream fileStream = new FileStream("temp.dat",FileMode.Create);然后创建二进制格式器:BinaryFormatter b=newBinaryFormatter();然后是序列化:b.Serialize(fileStream,c);,然后关闭保存流。(可以见下面的例子)

读取一个已经被序列化的对象的时候:操作方式一样,只是

5.           FileStream fileStream = new FileStream(

6.           "temp.dat", FileMode.Open,

7.           FileAccess.Read, FileShare.Read);

8.           ClassToSerialize c =

9.           (ClassToSerialize)b.Deserialize(fileStream);

然后就可以读取了,完整的例子是:

10.       using System;

11.       using System.IO;

12.       using System.Runtime.Serialization;

13.       using System.Runtime.Serialization.Formatters.Binary;

14.       public class SerialTest{

15.       public void SerializeNow(){

16.       ClassToSerialize c=new ClassToSerialize();

17.       FileStream fileStream = new FileStream(

18.       "temp.dat", FileMode.Create);

19.

20.       BinaryFormatter b=new BinaryFormatter();

21.       b.Serialize(fileStream,c);

22.       fileStream.Close();

23.       }

24.       public void DeSerializeNow(){

25.       ClassToSerialize c=new ClassToSerialize();

26.       FileStream fileStream = new FileStream(

27.       "temp.dat", FileMode.Open,

28.        FileAccess.Read,

29.        FileShare.Read);

30.       BinaryFormatter b=new BinaryFormatter();

31.       //SoapFormatter

32.       c=(ClassToSerialize)b.Deserialize(fileStream);

33.       Console.WriteLine(c.name);

34.       fileStream.Close();

35.       }

36.       public static void Main(string[] s){

37.       SerialTest st=new SerialTest();

38.       st.SerializeNow();

39.       st.DeSerializeNow();

40.       }

41.       }

42.       [Serializable]

43.       public class ClassToSerialize{

44.       public int id=100;

45.       public string name="Name";

46.       }

这就是自带的序列化和反序列的操作,但是,很多情况下,一个对象比较大,而且很多私有的属性和方法我们不需要,例如在原型模式里面序列化的话,只需要序列Clone方法和一些属性,私有的方法无需要,还例如在读取大规模的IO的时候,读取操作完全不需要... 这时候就需要自己集成重写序列的ISerializable接口:

实现该接口需要两个注意的,一个就是构造函数,主要是为了反序列,另一个就是GetObjectData,主要是执行序列化,例如我们现在有一个Employee类需要序列化

47.       [Serializable()]

48.       //Set this attribute to all the classes that want to serialize

49.       public class Employee : ISerializable

50.       //derive your class from ISerializable {

51.       public int EmpId;

52.       public string EmpName;

53.       [NonSerialized()]

54.       public string NoSerialString="NoSerialString-Test";

55.

56.       }

需要注意的是我这里的NoSerialString属性前面有[NonSerialized()],就是说默认并不序列化这个属性,而是使用默认值。

首先是构造函数:

57.       public Employee(SerializationInfo info, StreamingContext ctxt)

58.       {

59.       EmpId = (int)info.GetValue(

60.       "EmployeeId", typeof(int));

61.       EmpName = (String)info.GetValue(

62.       "EmployeeName", typeof(string));

63.       //NoSerialString =

64.       //(String)info.GetValue("NoSerialString", typeof(string));

65.       }

然后是C#序列化方法,就是当写入流的时候怎么保存的:

66.       public void GetObjectData(SerializationInfo info, StreamingContext ctxt) {

67.

68.       info.AddValue("EmployeeId", EmpId);

69.       info.AddValue("EmployeeName", EmpName);

70.       }

把上面两个方法写入到Employee类,然后写个测试的程序:

71.       public class ObjSerial{

72.       public static void Main(String[] args){

73.       Employee mp = new Employee();

74.       mp.EmpId = 10;

75.       mp.EmpName = "Omkumar";

76.       mp.NoSerialString = "你好啊";

77.

78.          //C#序列化和反序列化之序列化

79.       Stream stream = File.Open("EmployeeInfo.osl", FileMode.Create);

80.       BinaryFormatter bformatter = new BinaryFormatter();

81.

82.       Console.WriteLine("Writing Employee Information");

83.       bformatter.Serialize(stream, mp);

84.       stream.Close();

85.

86.

87.       mp = null;

88.          //C#序列化和反序列化之反序列

89.       stream = File.Open("EmployeeInfo.osl", FileMode.Open);

90.       bformatter = new BinaryFormatter();

91.

92.       Console.WriteLine("Reading Employee Information");

93.       mp = (Employee)bformatter.Deserialize(stream);

94.       stream.Close();

95.

96.       Console.WriteLine(

97.       "Employee Id: {0}",mp.EmpId.ToString());

98.       Console.WriteLine(

99.       "Employee Name: {0}",mp.EmpName);

100.     Console.WriteLine(

101.    
"Employee NoSerialString: {0}",mp.NoSerialString);

102.

103.     }

104.     }

C#序列化和反序列化程序执行的结果是:

105.     Writing Employee Information

106.     Reading Employee Information

107.     Employee Id: 10

108.     Employee Name: Omkumar

109.     Employee NoSerialString: NoSerialString-Test

看到Employee NoSerialString:属性的值没有,它保持默认值,没有序列化。

8.2 Xml格式序列化及反序列化

要序列化的对象的类:

  [Serializable]

  public class Person

  {

  private string name;

  public string Name

  {

  get

  {

  return name;

  }

  set

  {

  name=value;

  }

  }

  public string Sex;

  public int Age=31;

  public Course[] Courses;

  public Person()

  {

  }

  public Person(string Name)

  {

  name=Name;

  Sex="男";

  }

  }

  [Serializable]

  public class Course

  {

  public string Name;

  [XmlIgnore]public string Description;

  public Course()

  {

  }

  public Course(string name,string description)

  {

  Name=name;

  Description=description;

  }

  }

  进行序列化及反序列化的测试类:

  class Test

  {

  //序列化

  public void Serialiaze()

  {

  Person c=new Person("cyj")

  c.Courses=new Course[2];

  c.Courses[0]=new Course("英语","交流工具")

  c.Courses[1]=new Course("数学","自然科学")

  XmlSerializer xs=new XmlSerializer(typeof(Person));

  Stream stream = newFileStream("c:\\cyj.xml", FileMode.Create, FileAccess.Write,FileShare.ReadWrite);

  xs.Serialize(stream, c);

  stream.Close();

  }

  //反序列化

  public void Deserialize()

  {

  XmlSerializer xs=new XmlSerializer(typeof(Person));

  Stream stream = newFileStream("c:\\cyj.xml", FileMode.Open, FileAccess.Read,FileShare.ReadWrite);

  Person p=(Person)xs.Deserialize(stream);

  Console.WriteLine(p.Name);

  Console.WriteLine(p.Age.ToString());

  Console.WriteLine(p.Courses.Length.ToString());

  Console.Read();

  }

  }

  格式化后Xml的文档内容为:

  <?xml version="1.0"?>

  <Person xmlns:xsd=http://www.w3.org/2001/XMLSchemaxmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

  <Sex>男</Sex>

   <Age>31</Age>

   <Courses>

   <Course>

      <Name>英语</Name>

   </Course>

   <Course>

      <Name>数学</Name>

   </Course>

   </Courses>

      <Name>cyj</Name>

  </Person>

时间: 2024-10-10 21:12:03

C#三十一 序列化与反序列化的相关文章

接口测试基础三-Python序列化和反序列化

啥是序列化?啥是反序列化?这两个词听起来优点高大上的意思,其实呢不然,很简单的可以理解为: 序列化:将python的数据对象编码转换为json格式的字符串 反序列化:将json格式的字符串解码为python的数据对象 在python中提供了json库,我们将json导入,查看json库下面有哪些方法: >>> import json >>> print (json.__all__) ['dump', 'dumps', 'load', 'loads', 'JSONDeco

序列化和反序列化[转]

http://tech.meituan.com/serialization_vs_deserialization.html #摘要序列化和反序列化几乎是工程师们每天都要面对的事情,但是要精确掌握这两个概念并不容易:一方面,它们往往作为框架的一部分出现而湮没在框架之中:另一方面,它们会以其他更容易理解的概念出现,例如加密.持久化.然而,序列化和反序列化的选型却是系统设计或重构一个重要的环节,在分布式.大数据量系统设计里面更为显著.恰当的序列化协议不仅可以提高系统的通用性.强健性.安全性.优化系统性

序列化和反序列化-刘丁

#一.定义以及相关概念 互联网的产生带来了机器间通讯的需求,而互联通讯的双方需要采用约定的协议,序列化和反序列化属于通讯协议的一部分.通讯协议往往采用分层模型,不同模型每层的功能定义以及颗粒度不同,例如:TCP/IP协议是一个四层协议,而OSI模型却是七层协议模型.在OSI七层协议模型中展现层(Presentation Layer)的主要功能是把应用层的对象转换成一段连续的二进制串,或者反过来,把二进制串转换成应用层的对象--这两个功能就是序列化和反序列化. 一般而言,TCP/IP协议的应用层对

Json的序列化和反序列化

一.什么是Json:  Json[javascript对象表示方法],它是一个轻量级的数据交换格式,我们可以很简单的来读取和写它,并且它很容易被计算机转化和生成 二.Json的表现形式: 对象: var user = {"name":"fxhl","gender":"Male","qq":"1123166772"} 数组: var userlist = [{"user"

jackson实现序列化的反序列化解析

现在项目开发过程中,字符串的传递成为前后端交互的主要方式,主要是因为字符串不会出现乱码等问题,传送方式是字节码传递,效率比实体较安全. 常见的Json类库有Gson.JSON-lib和Jackson,fastjson(阿里提供,自称效率最高的)等,Jackson相对来说比较高效,在项目中主要使用Jackson进行JSON和Java对象转换,下面给出一些Jackson的JSON操作方法. 一,下载jackson http://wiki.fasterxml.com/JacksonDownload 二

序列化和反序列化1

本文来自:http://kb.cnblogs.com/page/515982/ 作者: 刘丁  来源: 美团技术团队  发布时间: 2015-04-23 17:01  阅读: 1541 次  推荐: 3   原文链接   [收藏] 摘要 序列化和反序列化几乎是工程师们每天都要面对的事情,但是要精确掌握这两个概念并不容易:一方面,它们往往作为框架的一部分出现而湮没在框架之中:另一方面,它们会以其他更容易理解的概念出现,例如加密.持久化.然而,序列化和反序列化的选型却是系统设计或重构一个重要的环节,

【转载】序列化和反序列化

#摘要序列化和反序列化几乎是工程师们每天都要面对的事情,但是要精确掌握这两个概念并不容易:一方面,它们往往作为框架的一部分出现而湮没在框架之中:另一方面,它们会以其他更容易理解的概念出现,例如加密.持久化.然而,序列化和反序列化的选型却是系统设计或重构一个重要的环节,在分布式.大数据量系统设计里面更为显著.恰当的序列化协议不仅可以提高系统的通用性.强健性.安全性.优化系统性能,而且会让系统更加易于调试.便于扩展.本文从多个角度去分析和讲解"序列化和反序列化",并对比了当前流行的几种序列

序列化和反序列化技术的分析和选择

转自:https://tech.meituan.com/serialization_vs_deserialization.html 美团点评技术团队的文章 #摘要序列化和反序列化几乎是工程师们每天都要面对的事情,但是要精确掌握这两个概念并不容易:一方面,它们往往作为框架的一部分出现而湮没在框架之中:另一方面,它们会以其他更容易理解的概念出现,例如加密.持久化.然而,序列化和反序列化的选型却是系统设计或重构一个重要的环节,在分布式.大数据量系统设计里面更为显著.恰当的序列化协议不仅可以提高系统的通

springboot学习(三)————使用HttpMessageConverter进行http序列化和反序列化

以下内容,如有问题,烦请指出,谢谢! 对象的序列化/反序列化大家应该都比较熟悉:序列化就是将object转化为可以传输的二进制,反序列化就是将二进制转化为程序内部的对象.序列化/反序列化主要体现在程序I/O这个过程中,包括网络I/O和磁盘I/O. 那么什么是http序列化和反序列化呢? 在使用springmvc时,我们经常会这样写: @RestController @RequestMapping("/users") public class UserController { @Auto