科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件.NET Framework中的串行化操作

.NET Framework中的串行化操作

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

.NET中的串行化允许编程人员获得一个对象的实例,并将它转换为一种易于在网络上传播或着在数据库、文件系统上存储的格式

作者:刘彦青 来源:YESKY 2007年11月4日

关键字:

  • 评论
  • 分享微博
  • 分享邮件
二进制和XML串行化的比较

  象上面表明的那样,选择XML或二进制串行化不取决于代码的实现。二种方法实现起来都非常简单。下面我们来考虑二种方法各自的优点。

  二进制串行化的优点

  1、无论是否是只读属性,所有成员都将被串行化。

  2、更高的性能。

  XML串行化的优点

  1、对象共享和使用方面更大的灵活性(互操作性)。

  2、不严格的二进制依赖

  3、可读性

  在研究Figure 1.1中的代码后,我们会发现,二进制和XML串行化仅仅依赖于对Formatter的选择。我们还会发现,串行化和反串行化之间的差别就在于是调用Serialize()还是Deserialize()。上面的代码能够原封不动地拷贝到我们的应用程序中,它将成为我们大多数串行化需求的核心
基本串行化和定制串行化的比较

  .NET Framework提供了二种完成串行化的方式。需要记住的是,完成串行化的方式与串行化的格式是二个不同的概念,执行串行化是指.NET Framework如何获得我们对象、以及如何将它转化为最后结果的实际方式,与格式(二进制还是XML格式无关)。最简单的方法是让.NET Framework自动地对对象进行串行化操作,这种方式被称作“基本串行化”。“基本串行化”只要求对象拥有类属性[Serializable()]即可,.NET Framework将获得我们的类,并将它转换为给定的格式。在这种方法中,我们唯一能够施加影响的是,使用[NonSerialized()]字段属性使任何字段式不会被串行化,我们无法对类中的每个字段是如何被串行化的提供精确的控制。

  如果希望对串行化处理有更多的控制,就需要使用“定制串行化”。在这种方式中,我们能够精确地指定哪个字段能够被串行化,以及如何进行串行化。在样例解决方案中,我们创建了一个名字为ScheduleCustom的类,正确地演示了“定制串行化”的用法。

  在使用“基本串行化”时,对象的版本是一个主要问题。要将Schedule对象串行化到磁盘上,然后改变该对象(例如,添加一个字段),在进行反串行化时就会出现问题,得到如下所示的错误信息:

“成员的数量发生错误,FifteenSeconds.Schedule对象有4个成员,被反串行化的成员数量为3。”

  如果碰上这一问题,就要考虑使用“定制串行化”了。由于能够在串行化处理过程中精确地控制类中的所有成员,我们就能够解决因版本而出现的问题。

  定制串行化

  我们需要作的第一件事就是明确地在类前面添加[Serializable()];第二,我们的类必须实现
System.Runtime.Serialization.ISerializable接口,因此,我们的类的定义应当如下所示:

[Serializable()]
public class ScheduleCustom : System.Runtime.Serialization.ISerializable {
 //在接口中,我们能够发现下面的一个方法:
 void GetObjectData(SerializationInfo info, StreamingContext context);
 //为了使类能够很好地支持这一接口,我们还必须实现下面的GetObjectData()方法:
 public void GetObjectData(SerializationInfo info,StreamingContext context) {
 //利用info对象添加需要进行串行化的字段
 info.AddValue("start", start);
 info.AddValue("end", end);
 info.AddValue("interval", interval);
}

  仅仅通过上面这个简单的例子,我们也许还不能深刻地体会到使用“定制串行化”的强大功能。下面,我们将增加类的复杂程度,演示“定制串行化”带给我们串行化需求的灵活性:

  如果我们要检查串行化过程中开始时DateTime值的输出,就会发现它使用了缺省的Framework DateTime格式:

  2002-08-19T14:09:13.3457440-07:00

  如果要与其他不使用.NET Framework的人合作,并国际化地发布应用程序,用格林威治时间来表示
DateTime值是比较明智的。下面我们来修改GetObjectData()方法,将开始和结束时的值转换为格林威治时间。

public void GetObjectData(SerializationInfo info,StreamingContext context) {
 //使用info对象添加需要串行化的字段
 //为了更好地与别人合作,我们将把时间转换为格林威治时间
 info.AddValue("start", System.TimeZone.CurrentTimeZone.ToUniversalTime(start));
 info.AddValue("end", System.TimeZone.CurrentTimeZone.ToUniversalTime(end));
 info.AddValue("interval", interval);
 info.AddValue("timeformat", "utc");
}

  8/19/2002 9:09:13 PM

  现在,转换时的起始时间将成为如下的格林威治时间形式:

  8/19/2002 9:09:13 PM

  注意,我添加了一个名字为“timeformat”的属性,在以后判断在串行化处理中使用哪种时间格式时,这一字段特别有用。

  也可以考虑用其他格式输出日期。考虑System.Globalization.DateTimeFormatInfo能够提供哪几种格式,例如,将DateTime转换为自Unix“诞生”(1979年1月1日)后的时间,这样可以更好地与非微软的平台进行集成)。我们也可以在类中添加一个可选的属性,判断在被串行化时DateTime使用的格式。

  定制反串行化

  如果希望使对象能够以定制方式被反串行化,需要使用一个定制构建器。该构建器的定义如下所示:

public ScheduleCustom (SerializationInfo info,StreamingContext context) {}

  我们必须实现这一方法。在schedule类中,我们的实现将把UTC(世界协调时间)转换为本机上的DateTime格式。

public ScheduleCustom (SerializationInfo info,StreamingContext context) {
 //我们将日期/时间转换回本地时间
 this.start = info.GetDateTime("start").ToLocalTime();
 this.end = info.GetDateTime("end").ToLocalTime();
 this.interval = info.GetInt32("interval");
}

  象我们在前面的“定制串行化”过程中指出的那样,添加的timeformat字段能够用来指定如何将串行化的时间转换为本地对象所必需的DateTime格式,但由于在本例中我们只进行了与UTC时间之间的转换,因此是相当简单的。

  使用Web服务的串行化

  在学习新的技术时,最重要的是学习这种技术如何使用。在这一部份中,我们将创建一个有二个方法的Web服务:第一个方法使Framework以二进制的形式返回我们定制串行化的schedule对象,第二个方法以XML的格式返回相同的对象。

  我们只要简单地添加一个带有指向上面的串行化工程引用的新C# Web服务工程即可,然后,我们再创建上面所述的二个方法:

FifteenSeconds.ScheduleCustom customSchedule =
new FifteenSeconds.ScheduleCustom(System.DateTime.Now, System.DateTime.Now.AddHours(5), 10000);

[WebMethod]
public byte[] Get_Binary_Schedule() {
 return FifteenSeconds.Serializer.Serialize( customSchedule,
 FifteenSeconds.Serializer.SerializationFormat.Binary).ToArray();
}
[WebMethod]
public string Get_XML_Schedule() {
 return FifteenSeconds.Serializer.ConvertStreamToString
 (FifteenSeconds.Serializer.Serialize( customSchedule,
 FifteenSeconds.Serializer.SerializationFormat.Xml));
}

  需要注意的是,二个方法都使用了FifteenSeconds.ScheduleCustom对象的同一个实例,在二进制形式中返回byte[]型数据,在XML形式中返回string型数据。

  需要记住的是,Framework将自动地串行化我们的对象,根据使用的方法返回适当类型的数据。另外,我们还需要一些时间研究解决方案中的Serialization工程,在将这些对象串行化为一个文件时,其中有些方法可能会有用。

  结论

  这篇文章演示了在应用程序中使用串行化是如何简单。在需要将一个对象的实例转换为能够方便地传输或保存的格式时,串行化可能就是一种选择。

查看本文来源

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章