.net中对象序列化技术

时间:2024-05-01 23:31:37

序列化是将对象状态转换为可保持或传输的格式的过程。与序列化相对的是反序列化,它将流转换为对象。这两个过程结合起来,可以轻松地存储和传输数据。例如,可以序列化一个对象,然后使用 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. namespace MySerializeDemo
  5. {
  6. [Serializable]
  7. /// <summary>
  8. /// 要序列化的对象
  9. /// 作者:周公
  10. /// 编写时间:2009-03-10
  11. /// </summary>
  12. public class MyObject
  13. {
  14. //[NonSerialized]
  15. private string name;
  16. private DateTime birthday;
  17. private string homePlace;
  18. /// <summary>
  19. /// 出生地
  20. /// </summary>
  21. public string HomePlace
  22. {
  23. get { return homePlace; }
  24. set { homePlace = value; }
  25. }
  26. /// <summary>
  27. /// 生日
  28. /// </summary>
  29. public DateTime Birthday
  30. {
  31. get { return birthday; }
  32. set { birthday = value; }
  33. }
  34. /// <summary>
  35. /// 姓名
  36. /// </summary>
  37. public string Name
  38. {
  39. get { return name; }
  40. set { name = value; }
  41. }
  42. /// <summary>
  43. /// 年龄
  44. /// </summary>
  45. public int Age
  46. {
  47. get { return DateTime.Now.Year - birthday.Year; }
  48. }
  49. /// <summary>
  50. /// override了ToString()方法
  51. /// </summary>
  52. /// <returns></returns>
  53. public override string ToString()
  54. {
  55. return string.Format("姓名:{0},生日:{1},出生地:{2},年龄:{3}",name,birthday,homePlace,Age);
  56. }
  57. }
  58. }

下面是分别用上面的三个类进行序列化和反序列化的代码:

  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. namespace MySerializeDemo
  10. {
  11. class Program
  12. {
  13. static void Main(string[] args)
  14. {
  15. MyObject obj = new MyObject();
  16. obj.Birthday = new DateTime(1979, 11, 7);
  17. obj.HomePlace = "湖北";
  18. obj.Name = "周公";
  19. Console.WriteLine("========使用BinaryFormatter类进行序列化和反序列化。====");
  20. BinarySerialize(obj);
  21. BinaryDeserialize("C://MyObject.dat");
  22. Console.WriteLine("========使用SoapFormatter类进行序列化和反序列化。====");
  23. SOAPSerialize(obj);
  24. SOAPDeserialize("C://MyObject.soap");
  25. Console.WriteLine("========使用XmlSerializer类进行序列化和反序列化。====");
  26. XMLSerialize(obj);
  27. XMLDeserialize("C://MyObject.xml");
  28. }
  29. /// <summary>
  30. /// 二进制序列化对象
  31. /// </summary>
  32. /// <param name="obj"></param>
  33. public static void BinarySerialize(MyObject obj)
  34. {
  35. using (FileStream stream = new FileStream("C://MyObject.dat", FileMode.Create, FileAccess.Write))
  36. {
  37. BinaryFormatter formater = new BinaryFormatter();
  38. formater.Serialize(stream, obj);
  39. Console.WriteLine("对象已经被序列化。" + obj.ToString());
  40. }
  41. }
  42. /// <summary>
  43. /// 二进制反序列化
  44. /// </summary>
  45. /// <param name="fileName"></param>
  46. public static void BinaryDeserialize(string fileName)
  47. {
  48. using (FileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read))
  49. {
  50. BinaryFormatter formater = new BinaryFormatter();
  51. MyObject obj=(MyObject)formater.Deserialize(stream);
  52. Console.WriteLine("对象已经被反序列化。" + obj.ToString());
  53. }
  54. }
  55. /// <summary>
  56. /// 二进制序列化对象
  57. /// </summary>
  58. /// <param name="obj"></param>
  59. public static void SOAPSerialize(MyObject obj)
  60. {
  61. using (FileStream stream = new FileStream("C://MyObject.soap", FileMode.Create, FileAccess.Write))
  62. {
  63. SoapFormatter formater = new SoapFormatter();
  64. formater.Serialize(stream, obj);
  65. Console.WriteLine("对象已经被序列化。" + obj.ToString());
  66. }
  67. }
  68. /// <summary>
  69. /// 二进制反序列化
  70. /// </summary>
  71. /// <param name="fileName"></param>
  72. public static void SOAPDeserialize(string fileName)
  73. {
  74. using (FileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read))
  75. {
  76. SoapFormatter formater = new SoapFormatter();
  77. MyObject obj = (MyObject)formater.Deserialize(stream);
  78. Console.WriteLine("对象已经被反序列化。" + obj.ToString());
  79. }
  80. }
  81. /// <summary>
  82. /// XML序列化
  83. /// </summary>
  84. /// <param name="obj"></param>
  85. public static void XMLSerialize(MyObject obj)
  86. {
  87. using (FileStream stream = new FileStream("C://MyObject.xml", FileMode.Create, FileAccess.Write))
  88. {
  89. XmlSerializer serializer = new XmlSerializer(typeof(MyObject));
  90. serializer.Serialize(stream, obj);
  91. Console.WriteLine("对象已经被序列化。" + obj.ToString());
  92. }
  93. }
  94. /// <summary>
  95. /// XML反序列化
  96. /// </summary>
  97. /// <param name="fileName"></param>
  98. public static void XMLDeserialize(string fileName)
  99. {
  100. using (FileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read))
  101. {
  102. XmlSerializer serializer = new XmlSerializer(typeof(MyObject));
  103. MyObject obj = (MyObject)serializer.Deserialize(stream);
  104. Console.WriteLine("对象已经被反序列化。" + obj.ToString());
  105. }
  106. }
  107. }
  108. }

可见通过上面三个类都能实现将对象序列化保存,并且都能反序列化还原到对象被序列化之前的状态(这正是序列化意义所在,能保存对象运行时的状态并且还能还原)。如果运行上面的代码会在C盘根目录下创建三个文件,分别是MyObject.dat、MyObject.soap和MyObject.xml文件,因为MyObject.dat是二进制文件,所以无法查看文件的内容,但是我们可以打开MyObject.soap和MyObject.xml这两个文件。