Chinaunix首页 | 论坛 | 博客
  • 博客访问: 846854
  • 博文数量: 366
  • 博客积分: 10267
  • 博客等级: 上将
  • 技术积分: 4290
  • 用 户 组: 普通用户
  • 注册时间: 2012-02-24 14:04
文章分类

全部博文(366)

文章存档

2012年(366)

分类: 系统运维

2012-04-22 20:01:15

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

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

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

  4. 1、使用BinaryFormatter进行串行化

  5. 下面是一个可串行化的类:





  6. using System;

  7. using System.Data;

  8. using System.Configuration;

  9. using System.Web;

  10. using System.Web.Security;

  11. using System.Web.UI;

  12. using System.Web.UI.WebControls;

  13. using System.Web.UI.WebControls.WebParts;

  14. using System.Web.UI.HtmlControls;

  15. using System.IO;

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

  17. /**////

  18. /// ClassToSerialize 的摘要说明

  19. ///

  20. [Serializable]

  21. publicclass ClassToSerialize

  22. {

  23. publicint id = 100;

  24. publicstring name = "Name";

  25. [NonSerialized]

  26. publicstring *** = "男";

  27. }



  28. 下面是串行化和反串行化的方法:

  29. publicvoid SerializeNow()

  30. {

  31. ClassToSerialize c = new ClassToSerialize();

  32. FileStream fileStream = new FileStream("c://temp.dat", FileMode.Create);

  33. BinaryFormatter b = new BinaryFormatter();

  34. b.Serialize(fileStream, c);

  35. fileStream.Close();

  36. }

  37. publicvoid DeSerializeNow()

  38. {

  39. ClassToSerialize c = new ClassToSerialize();

  40. c.*** = "kkkk";

  41. FileStream fileStream = new FileStream("c://temp.dat", FileMode.Open, FileAccess.Read, FileShare.Read);

  42. BinaryFormatter b = new BinaryFormatter();

  43. c = b.Deserialize(fileStream) as ClassToSerialize;

  44. Response.Write(c.name);

  45. Response.Write(c.***);

  46. fileStream.Close();

  47. }

  48. 调用上述两个方法就可以看到串行化的结果:***属性因为被标志为[NonSerialized],故其值总是为null

  49. 2、使用SoapFormatter进行串行化

  50. 和BinaryFormatter类似,我们只需要做一下简单修改即可:

  51. a.将using语句中的.Formatter.Binary改为.Formatter.Soap;

  52. b.将所有的BinaryFormatter替换为SoapFormatter.

  53. c.确保报存文件的扩展名为.xml

  54. 经过上面简单改动,即可实现SoapFormatter的串行化,这时候产生的文件就是一个xml格式的文件。

  55. 3、使用XmlSerializer进行串行化

  56. 关于格式化器还有一个问题,假设我们需要XML,但是不想要SOAP特有的额外信息,那么我们应该怎么办呢?有两中方案:要么编写一个实现 IFormatter接口的类,采用的方式类似于SoapFormatter类,但是没有你不需要的信息;要么使用库类XmlSerializer,这个 类不使用Serializable属性,但是它提供了类似的功能。

  57. 如果我们不想使用主流的串行化机制,而想使用XmlSeralizer进行串行化我们需要做一下修改:

  58. a.添加System.Xml.Serialization命名空间。

  59. b.Serializable和NoSerialized属性将被忽略,而是使用XmlIgnore属性,它的行为与NoSerialized类似。

  60. c.XmlSeralizer要求类有个默认的构造器,这个条件可能已经满足了。

  61. 下面看示例:

  62. 要序列化的类:

  63. using System;

  64. using System.Data;

  65. using System.Configuration;

  66. using System.Web;

  67. using System.Web.Security;

  68. using System.Web.UI;

  69. using System.Web.UI.WebControls;

  70. using System.Web.UI.WebControls.WebParts;

  71. using System.Web.UI.HtmlControls;

  72. using System.Xml.Serialization;

  73. [Serializable]

  74. publicclass Person

  75. {

  76. privatestring name;

  77. publicstring Name

  78. {

  79. get

  80. {

  81. return name;

  82. }

  83. set

  84. {

  85. name = value;

  86. }

  87. }





  88. publicstring ***;

  89. publicint Age = 31;

  90. public Course[] Courses;



  91. public Person()

  92. {

  93. }

  94. public Person(string Name)

  95. {

  96. name = Name;

  97. *** = "男";

  98. }

  99. }

  100. [Serializable]

  101. publicclass Course

  102. {

  103. publicstring Name;

  104. [XmlIgnore]

  105. publicstring Description;

  106. public Course()

  107. {

  108. }

  109. public Course(string name, string description)

  110. {

  111. Name = name;

  112. Description = description;

  113. }

  114. }



  115. 序列化和反序列化方法:

  116. publicvoid XMLSerialize()

  117. {

  118. Person c = new Person("cyj");

  119. c.Courses = new Course[2];

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

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

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

  123. Stream stream = new FileStream("c://cyj.XML",FileMode.Create,FileAccess.Write,FileShare.Read);

  124. xs.Serialize(stream,c);

  125. stream.Close();

  126. }

  127. publicvoid XMLDeserialize()

  128. {

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

  130. Stream stream = new FileStream("C://cyj.XML",FileMode.Open,FileAccess.Read,FileShare.Read);

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

  132. Response.Write(p.Name);

  133. Response.Write(p.Age.ToString());

  134. Response.Write(p.Courses[0].Name);

  135. Response.Write(p.Courses[0].Description);

  136. Response.Write(p.Courses[1].Name);

  137. Response.Write(p.Courses[1].Description);

  138. stream.Close();

  139. }

  140. 这里Course类的Description属性值将始终为null,生成的xml文档中也没有该节点,如下图:

  141. "1.0"?>

  142. "" xmlns:xsd="">

  143. <***>男

  144. 31



  145. 英语

  146. 交流工具



  147. 数学

  148. 自然科学



  149. cyj


  150. 4、自定义序列化

  151. 如果你希望让用户对类进行串行化,但是对数据流的组织方式不完全满意,那么可以通过在自定义类中实现接口来自定义串行化行为。这个接口只有一个方 法,GetObjectData. 这个方法用于将对类对象进行串行化所需要的数据填进SerializationInfo对象。你使用的格式化器将构造SerializationInfo 对象,然后在串行化时调用GetObjectData. 如果类的父类也实现了ISerializable,那么应该调用GetObjectData的父类实现。

  152. 如果你实现了ISerializable,那么还必须提供一个具有特定原型的构造器,这个构造器的参数列表必须与GetObjectData相同。这个构造器应该被声明为私有的或受保护的,以防止粗心的开发人员直接使用它。

  153. 示例如下:

  154. 实现ISerializable的类:

  155. using System;

  156. using System.Data;

  157. using System.Configuration;

  158. using System.Web;

  159. using System.Web.Security;

  160. using System.Web.UI;

  161. using System.Web.UI.WebControls;

  162. using System.Web.UI.WebControls.WebParts;

  163. using System.Web.UI.HtmlControls;

  164. using System.Runtime.Serialization;

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

  166. /**////

  167. /// Employee 的摘要说明

  168. ///

  169. [Serializable]

  170. publicclass Employee:ISerializable

  171. {

  172. publicint EmpId=100;

  173. publicstring EmpName="刘德华";

  174. [NonSerialized]

  175. publicstring NoSerialString = "NoSerialString-Test";

  176. public Employee()

  177. {

  178. //

  179. // TODO: 在此处添加构造函数逻辑

  180. //

  181. }

  182. private Employee(SerializationInfo info, StreamingContext ctxt)

  183. {

  184. EmpId = (int)info.GetValue("EmployeeId", typeof(int));

  185. EmpName = (String)info.GetValue("EmployeeName",typeof(string));

  186. //NoSerialString = (String)info.GetValue("EmployeeString",typeof(string));

  187. }

  188. publicvoid GetObjectData(SerializationInfo info, StreamingContext ctxt)

  189. {

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

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

  192. //info.AddValue("EmployeeString", NoSerialString);

  193. }

  194. }



  195. 序列化和反序列化方法:

  196. publicvoid OtherEmployeeClassTest()

  197. {

  198. Employee mp = new Employee();

  199. mp.EmpId = 10;

  200. mp.EmpName = "邱枫";

  201. mp.NoSerialString = "你好呀";

  202. Stream steam = File.Open("c://temp3.dat", FileMode.Create);

  203. BinaryFormatter bf = new BinaryFormatter();

  204. Response.Write("Writing Employee Info:");

  205. bf.Serialize(steam,mp);

  206. steam.Close();

  207. mp = null;

  208. //反序列化

  209. Stream steam2 = File.Open("c://temp3.dat", FileMode.Open);

  210. BinaryFormatter bf2 = new BinaryFormatter();

  211. Response.Write("Reading Employee Info:");

  212. Employee mp2 = (Employee)bf2.Deserialize(steam2);

  213. steam2.Close();

  214. Response.Write(mp2.EmpId);

  215. Response.Write(mp2.EmpName);

  216. Response.Write(mp2.NoSerialString);

  217. }
阅读(1751) | 评论(2) | 转发(0) |
给主人留下些什么吧!~~

十七岁的回忆2012-04-24 10:19:18

反序列化的操作怎么说?

泥亚鳅2012-04-23 21:24:39

- -asp.net序列化类中能有ILST方法吗??