序列化又称串行化,是.NET运行时环境用来支持用户定义类型的流化的机制。其目的是以某种存储造成使自定义对象持久化,或者将这种对象从一个地方传输到另外一个地方。
.NET框架提供了两种串行化的方式:一、是使用BinaryFormatter进行串行化;二、使用SoapFormatter进行串行化;三、使用XmlSerializer进行串行化。第一种方式提供了一个简单的二进制数据流以及某些附加的类型信息,而第二种将数据流格式化为XML存储;第三种其实和第二种差很少也是XML的格式存储,只不过比第二种的XML格式要简化不少(去掉了SOAP特有的额外信息)。
可使用[Serializable]属性将类标志为可序列化的。若是某个类的元素不想被序列化,一、2可使用[NonSerialized]属性来标志,二、可使用[XmlIgnore]来标志。服务器
重点:框架
Ø 理解序列化 / 反序列化概念函数
Ø 可以使用序列化/反序列化保持和恢复对象状态工具
预习功课:测试
Ø 序列化的概念this
Ø 反序列化的概念spa
Ø 如何使用序列化和反序列化保持和恢复对象状态orm
Ø 如何利用序列化来操做Xml文件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>