本文将从这两个格式器入手,先向大家介绍分别用它们如何实现序列化和反序列化,然后比较两种格式器的不同点。接着我会向大家介绍实现序列化对对象类型的一些要求,同时还要向大家介绍两种不同的序列化方式:基本序列化(Basic Serialization)和自定义序列化(Custom Serialization)。最后,我还会给大家介绍一个实例程序以加深大家对序列化机制的理解程度。

  程序员在编写应用程序的时候往往要将程序的某些数据存储在内存中,然后将其写入某个文件或是将它传输到网络中的另一台计算机上以实现通讯。这个将程序数据转化成能被存储并传输的格式的过程被称为"序列化"Serialization),而它的逆过程则可被称为"反序列化"Deserialization)。

  .Net框架对序列化机制具有非常好的支持,它提供了两个名字空间(namespace):System.Runtime.SerializationSystem.Runtime.Serialization.Formatters以完成序列化机制的大部分功能。系列化这项技术可以应用在将程序产生的结果数据存储到文件系统中,但是它更主要的应用是在于.Net RemotingWeb服务的实现上。

  序列化机制的实现是依靠格式器(Formatter)而完成的,它是一个从System.Runtime.Serialization.IFormatter继承下来的类的对象。格式器完成了将程序数据转化到能被存储并传输的格式的工作,同时也完成了将数据转化回来的工作。.Net框架为程序员提供了两种类型的格式器,一种通常是应用于桌面类型的应用程序的,它一个是System.Runtime.Serialization.Formatters.Binary.BinaryFormatter类的对象,而另一种则更主要的应用于.Net RemotingXML Web服务等领域的,它一个是System.Runtime.Serialization.Formatters.Soap.SoapFormatter类的对象。从它们的名称来看,我们不妨将它们分别称为二进制格式器和XML格式器。

  

 

  下面我先向大家介绍两种不同的格式器,分别用它们如何实现序列化机制和反序列化机制,请看下面的代码:

 

#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

从上面的代码我们可以发现无论运用哪种格式器,其基本的过程都是一样的,而且都是非常容易实现的,唯一的不同就是定义格式器的类型不同。不过在实际的应用中,二进制格式器往往应用于一般的桌面程序和网络通讯程序中,而XML格式器禀承了XML技术的优点,大多数被应用于.Net RemotingXML Web服务等领域。下面我们来分析一下两种格式器各自的优点。

 

  二进制序列化的优点:

  1所有的类成员(包括只读的)都可以被序列化;

  2性能非常好。

 

  XML序列化的优点:

  1互操作性好;

  2不需要严格的二进制依赖;

  3可读性强。

  通过分析上面的代码,我们知道了选择二进制序列化的方式还是选择XML序列化的方式仅仅是对不同的格式器进行选择而已。你可以根据实际的需要选择相应的格式器完成序列化和反序列化工作。同时请注意,代码中的序列化函数和反序列化函数仅仅是在调用Serialize()和Deserialize()这两个核心函数上产生了差别,即它们的参数不同。因此以上的代码完成了一些最最基本但是很重要的功能,你可以将它们运用在你的程序中,或是将其进行适当扩充以满足程序的特定需要。

 

 二、序列化机制对类的要求

  如果你要对一个对象进行序列化,那么你必须将它的类型标记为[Serializable()],该操作是通过SerializableAttribute属性来实现的。将SerializableAttribute属性应用于一种数据类型可表明该数据类型的实例可以被序列化。如果正在序列化的对象图中的任何类型未应用SerializableAttribute属性,公共语言运行库则会引发SerializationException。默认情况下,类型中由SerializableAttribute标记的所有公共和私有字段都会进行序列化,除非该类型实现ISerializable接口来重写序列化进程(通过实现该接口我们便可以实现将在后面介绍的"自定义序列化")。默认的序列化进程会排除用NonSerializedAttribute属性标记的字段,即你可以将该类型标记为[NonSerialized()]以表明它是不可以被序列化的。如果可序列化类型的字段包含指针、句柄或其他某些针对于特定环境的数据结构,并且不能在不同的环境中以有意义的方式重建,则最好将NonSerializedAttribute属性应用于该字段。有关序列化的更多信息,请参阅System.Runtime.Serialization名字空间中的相关内容。

  下面我给大家介绍一个例子,以显示如何正确的运用SerializableAttribute属性和NonSerializedAttribute属性。该程序中运用到了XML格式器,不过同时给出了二进制格式器为参考(程序中将其用"//"标注),其实现的结果是一样的。该程序实现的功能是在序列化和反序列化操作前后测试对象因包含了[NonSerialized()]的字段而显示不同的屏幕打印结果。其代码如下:

 

using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Soap;
//using System.Runtime.Serialization.Formatters.Binary;
 
public class Test {
 public static void Main() {
  // 创建一个新的测试对象
  TestSimpleObject obj = new TestSimpleObject();
 
  Console.WriteLine("Before serialization the object contains: ");
  obj.Print();
 
  // 创建一个文件"data.xml"并将对象序列化后存储在其中
  Stream stream = File.Open("data.xml", FileMode.Create);
  SoapFormatter formatter = new SoapFormatter();
  //BinaryFormatter formatter = new BinaryFormatter();
 
  formatter.Serialize(stream, obj);
  stream.Close();
  
  // 将对象置空
  obj = null;
 
  // 打开文件"data.xml"并进行反序列化得到对象
  stream = File.Open("data.xml", FileMode.Open);
  formatter = new SoapFormatter();
  //formatter = new BinaryFormatter();
 
  obj = (TestSimpleObject)formatter.Deserialize(stream);
  stream.Close();
 
  Console.WriteLine("");
  Console.WriteLine("After deserialization the object contains: ");
  obj.Print();
 }
}
 
// 一个要被序列化的测试对象的类
[Serializable()]
 public class TestSimpleObject {
 public int member1;
 public string member2;
 public string member3;
 public double member4;
 
 // 标记该字段为不可被序列化的
[NonSerialized()] public string member5;
 
public TestSimpleObject() {
 member1 = 11;
 member2 = "hello";
 member3 = "hello";
 member4 = 3.14159265;
 member5 = "hello world!";
}
 
public void Print() {
 Console.WriteLine("member1 = '{0}'", member1);
 Console.WriteLine("member2 = '{0}'", member2);
 Console.WriteLine("member3 = '{0}'", member3);
 Console.WriteLine("member4 = '{0}'", member4);
 Console.WriteLine("member5 = '{0}'", member5);
}
}
View Code

相关文章:

  • 2021-08-06
  • 2021-12-11
  • 2022-12-23
  • 2022-12-23
  • 2021-11-01
  • 2021-08-06
  • 2022-12-23
猜你喜欢
  • 2021-06-07
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-11-29
  • 2022-12-23
  • 2021-12-18
相关资源
相似解决方案