序列化是将对象状态转换为可保持或传输的格式的过程。与序列化相对的是反序列化,它将流转换为对象。这两个过程结合起来,可以轻松地存储和传输数据。例如,可以序列化一个对象,然后使用 HTTP 通过 Internet 在客户端和服务器之间传输该对象。反之,反序列化根据流重新构造对象。此外还可以将对象序列化后保存到本地,再次运行的时候可以从本地文件中“恢复”对象到序列化之前的状态。
在.net中有提供了几种序列化的方式:
二进制序列化
XML序列化
SOAP序列化
二进制序列化所谓二进制序列化,指的是对象序列化之后是二进制形式的。二进制序列化是通过BinaryFormatter类来实现的,这个类位于System.Runtime.Serialization.Formatters.Binary命名空间下。
XML序列化
所谓XML序列化,是指对象序列化之后的结果是XML形式的。保存XML序列化是通过XmlSerializer 类来实现的, 这个类位于System.Xml.Serialization命名空间下。
SOAP序列化
所谓SOAP序列化是指对象序列化之后的结果符合SOAP协议,也就是可以通过SOAP协议传输(不知道SOAP协议?百度一下吧)。SOAP序列化是通过SoapFormatter类来实现的,这个类位于System.Runtime.Serialization.Formatters.Soap命名空间下,并且需要注意需要手动添加对这个命名空间的引用。
下面编写一个类用于序列化和反序列化,这个类的代码如下:
1. using System;
2. using System.Collections.Generic;
3. using System.Text;
4.
5. namespace MySerializeDemo
6. {
7. [Serializable]
8. /// <summary>
9. /// 要序列化的对象
10. /// 作者:周公
11. /// 编写时间:2009-03-10
12. /// </summary>
13. public class MyObject
14. {
15. //[NonSerialized]
16. private string name;
17. private DateTime birthday;
18. private string homePlace;
19. /// <summary>
20. /// 出生地
21. /// </summary>
22. public string HomePlace
23. {
24. get { return homePlace; }
25. set { homePlace = value; }
26. }
27.
28. /// <summary>
29. /// 生日
30. /// </summary>
31. public DateTime Birthday
32. {
33. get { return birthday; }
34. set { birthday = value; }
35. }
36.
37. /// <summary>
38. /// 姓名
39. /// </summary>
40. public string Name
41. {
42. get { return name; }
43. set { name = value; }
44. }
45.
46. /// <summary>
47. /// 年龄
48. /// </summary>
49. public int Age
50. {
51. get { return DateTime.Now.Year - birthday.Year; }
52. }
53. /// <summary>
54. /// override了ToString()方法
55. /// </summary>
56. /// <returns></returns>
57. public override string ToString()
58. {
59. return string.Format("姓名:{0},生日:{1},出生地:{2},年龄:{3}",name,birthday,homePlace,Age);
60. }
61.
62. }
63. }
下面是分别用上面的三个类进行序列化和反序列化的代码:
1. using System;
2. using System.Collections.Generic;
3. using System.Text;
4. using System.IO;
5. using System.Runtime.Serialization.Formatters;
6. using System.Runtime.Serialization.Formatters.Binary;
7. using System.Runtime.Serialization.Formatters.Soap;
8. using System.Xml.Serialization;
9.
10. namespace MySerializeDemo
11. {
12. class Program
13. {
14. static void Main(string[] args)
15. {
16. new MyObject();
17. new DateTime(1979, 11, 7);
18. "湖北";
19. "周公";
20. "========使用BinaryFormatter类进行序列化和反序列化。====");
21. BinarySerialize(obj);
22. "C://MyObject.dat");
23. "========使用SoapFormatter类进行序列化和反序列化。====");
24. SOAPSerialize(obj);
25. "C://MyObject.soap");
26. "========使用XmlSerializer类进行序列化和反序列化。====");
27. XMLSerialize(obj);
28. "C://MyObject.xml");
29. }
30. /// <summary>
31. /// 二进制序列化对象
32. /// </summary>
33. /// <param name="obj"></param>
34. public static void BinarySerialize(MyObject obj)
35. {
36. using (FileStream stream = new FileStream("C://MyObject.dat", FileMode.Create, FileAccess.Write))
37. {
38. new BinaryFormatter();
39. formater.Serialize(stream, obj);
40. "对象已经被序列化。" + obj.ToString());
41. }
42. }
43. /// <summary>
44. /// 二进制反序列化
45. /// </summary>
46. /// <param name="fileName"></param>
47. public static void BinaryDeserialize(string fileName)
48. {
49. using (FileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read))
50. {
51. new BinaryFormatter();
52. MyObject obj=(MyObject)formater.Deserialize(stream);
53. "对象已经被反序列化。" + obj.ToString());
54. }
55. }
56.
57. /// <summary>
58. /// 二进制序列化对象
59. /// </summary>
60. /// <param name="obj"></param>
61. public static void SOAPSerialize(MyObject obj)
62. {
63. using (FileStream stream = new FileStream("C://MyObject.soap", FileMode.Create, FileAccess.Write))
64. {
65. new SoapFormatter();
66. formater.Serialize(stream, obj);
67. "对象已经被序列化。" + obj.ToString());
68. }
69. }
70. /// <summary>
71. /// 二进制反序列化
72. /// </summary>
73. /// <param name="fileName"></param>
74. public static void SOAPDeserialize(string fileName)
75. {
76. using (FileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read))
77. {
78. new SoapFormatter();
79. MyObject obj = (MyObject)formater.Deserialize(stream);
80. "对象已经被反序列化。" + obj.ToString());
81. }
82. }
83. /// <summary>
84. /// XML序列化
85. /// </summary>
86. /// <param name="obj"></param>
87. public static void XMLSerialize(MyObject obj)
88. {
89. using (FileStream stream = new FileStream("C://MyObject.xml", FileMode.Create, FileAccess.Write))
90. {
91. new XmlSerializer(typeof(MyObject));
92. serializer.Serialize(stream, obj);
93. "对象已经被序列化。" + obj.ToString());
94. }
95. }
96. /// <summary>
97. /// XML反序列化
98. /// </summary>
99. /// <param name="fileName"></param>
100. public static void XMLDeserialize(string fileName)
101. {
102. using (FileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read))
103. {
104. new XmlSerializer(typeof(MyObject));
105. MyObject obj = (MyObject)serializer.Deserialize(stream);
106. "对象已经被反序列化。" + obj.ToString());
107. }
108. }
109. }
110. }
可见通过上面三个类都能实现将对象序列化保存,并且都能反序列化还原到对象被序列化之前的状态(这正是序列化意义所在,能保存对象运行时的状态并且还能还原)。如果运行上面的代码会在C盘根目录下创建三个文件,分别是MyObject.dat、MyObject.soap和MyObject.xml文件,因为MyObject.dat是二进制文件,所以无法查看文件的内容,但是我们可以打开MyObject.soap和MyObject.xml这两个文件。