简介
.NET中的串行化允许编程人员获得一个对象的实例,并将它转换为一种易于在网络上传播或着在数据库、文件系统上存储的格式。该对象实际上是一个定制类型(包括我们已经设置的任何属性或字段)的实例。 我能想到的一些例子包括通过Web服务等向本地或远程应用程序的另一部分发送对象实例的能力。选择串行化的另一个例子是在正常情况下存储在数据库中的对象的数据,但数据的一部分无需个别地进行存储。通过只将需要查询的数据列成单独的字段,数据的其余部份可以在一个定制类型内进行简单的串行化,并在数据库中存储为一个完整的对象。
下面我们举一个调度对象的例子。这一调度对象能够使应用程序根据一个特定的进度表触发事件。在开发调度对象时,需要考虑许多设置,例如时间间隔、日期和时间限制等。当对于下一个事件应当何时被触发真正重要的信息片断是精确的日期/时间时,正常情况下,数据的每个部份都要求在表中创建一个单独的字段。现在,我们将整个调度对象串行化,并与下一次事件发生的日期/时间一起存储在数据库中,这样,使得整个数据库只包含有3个字段。
本文包含了可以将对象串行化为的二种格式:XML或二进制,其中每种形式都各有优缺点。本文还论述了串行化的二种方式:基本串行化和定制串行化。最后,文章将以一个实例演示如何通过互联网发送一个定制对象的例子。
任何串行化处理的第一步都是获取对象的实例,并将它转化为一种内存流。下面的代码演示了完成串行化的4个方法:二进制以及XML的串行化、反串行化。在后面的内容中,我们将论述二进制、XML串行化的区别:
Figure 1.1 核心的串行化方法
#region Binary Serializers public static System.IO.MemoryStream SerializeBinary(object request) { System.Runtime.Serialization.Formatters.Binary.BinaryFormatter serializer = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); System.IO.MemoryStream memStream = new System.IO.MemoryStream(); serializer.Serialize(memStream, request); return memStream; }
public static object DeSerializeBinary(System.IO.MemoryStream memStream) { memStream.Position=0; System.Runtime.Serialization.Formatters.Binary.BinaryFormatter deserializer = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); object newobj = deserializer.Deserialize(memStream); memStream.Close(); return newobj; } #endregion
#region XML Serializers
public static System.IO.MemoryStream SerializeSOAP(object request) {
System.Runtime.Serialization.Formatters.Soap.SoapFormatter serializer = new System.Runtime.Serialization.Formatters.Soap.SoapFormatter(); System.IO.MemoryStream memStream = new System.IO.MemoryStream(); serializer.Serialize(memStream, request); return memStream; }
public static object DeSerializeSOAP(System.IO.MemoryStream memStream) { object sr; System.Runtime.Serialization.Formatters.Soap.SoapFormatter deserializer = new System.Runtime.Serialization.Formatters.Soap.SoapFormatter(); memStream.Position=0; sr = deserializer.Deserialize(memStream); memStream.Close(); return sr; } #endregion | 如果想对一个对象进行串行化处理,可以在它的前面添加[Serializable()]标志,给类添加一个定制串行化属性。在下面“Serialization”工程中的Schedule类中,我们会看到这一属性。同时,我们还要考虑名字为[NonSerialized()]的字段属性,它可以用于类中的所有字段,防止它被串行化,如果在类中有一个字段不需要或者我们不希望在正式产品中对某个字段进行串行化处理,这一点是非常有用的。只要简单地在变量前添加NonSerialized()属性即可,因为系统不会自动地对该变量进行串行化处理。
需要记住的是,[Serializable()]属性适用于整个类,因此如果希望整个类都支持串行化,我们必须添加属性,而[NonSerialized()]属性只适用于被标志为[Serializable()]的类中的字段。使用[NonSerialized()]有时被称作“有选择性的串行化”。
最后,需要记住的是,为了使用System.Runtime.Serialization.Formatters.Soap.SoapFormatter,我们必须添加System.Runtime.Serialization.Formatters.Soap.dll的引用。
Figure 1.2 Schedule类
using System;
namespace FifteenSeconds { /// /// 允许我们提出一个计划 /// [Serializable()] public class Schedule { protected System.DateTime start; protected System.DateTime end;
//每次间隔增加的毫秒数 protected long interval;
public System.DateTime Start {get{return start;}set{start=value;}} public System.DateTime End {get{return end;}set{end=value;}} public long Interval {get{return interval;}set{interval=value;}} public Schedule(System.DateTime Start, System.DateTime End, long Interval) { start=Start; end=End; interval=Interval; } //返回下次运行的时间;如果计划已经结束,则返回结束时间 public System.DateTime NextRunTime { get { System.TimeSpan ts = new System.TimeSpan(end.Ticks-System.DateTime.Now.Ticks); if(ts.Milliseconds>0) { //运行时间还没有结束 return System.DateTime.Now.AddMilliseconds(interval); } else { return end; } } } }
} |
|
|