序列化是将对象转换成易于传输的形式的过程。例如,可以序列化对象,并使用 HTTP 通过 Internet 在客户端和服务器之间进行传输。另一方面,反序列化在流中重新构建对象。介绍两种常用的(反)序列化方法:

1,XML 序列化

XML 序列化只将对象的公共字段和属性值序列化为 XML 流。XML 序列化不包括类型信息。例如,如果 Library 命名空间中存在 Book 对象,则不能保证将它反序列化为同一类型的对象。

(1)如何序列化

要序列化对象,首先应创建要序列化的对象,然后设置其公共属性和字段。为此,必须确定 XML 流的传输格式,即它是作为流还是作为文件进行存储。例如,如果 XML 流必须以永久形式保存,则应创建 FileStream 对象。

1.创建对象并设置其公共字段和属性。
2.使用对象的类型构造 XmlSerializer。有关更多信息,请参见 XmlSerializer 类构造函 数。
3.调用 Serialize 方法生成对象的公共属性和字段的 XML 流或文件表示形式。下面的示例将创建一个文件。

 
  
  1. MySerializableClass myObject = new MySerializableClass();  
  2. // Insert code to set properties and fields of the object.  
  3. XmlSerializer mySerializer = new   
  4. XmlSerializer(typeof(MySerializableClass));  
  5. // To write to a file, create a StreamWriter object.  
  6. StreamWriter myWriter = new StreamWriter("myFileName.xml");  
  7. mySerializer.Serialize(myWriter, myObject);  
  8. myWriter.Close(); 

 (2)如何反序列化

当您反序列化对象时,传输格式确定您将创建流还是文件对象。确定了传输格式之后,就可以根据需要调用 Serialize 或 Deserialize 方法。

1.使用要反序列化的对象的类型构造 XmlSerializer。
2.调用 Deserialize 方法以生成该对象的副本。在反序列化时,必须将返回的对象强制转换为原始对象的类型,如下面的示例中所示,该示例将该对象反序列化为文件(尽管也可以将该对象反序列化为流)。

 
  
  1. MySerializableClass myObject;  
  2. // Construct an instance of the XmlSerializer with the type  
  3. // of object that is being deserialized.  
  4. XmlSerializer mySerializer =   
  5. new XmlSerializer(typeof(MySerializableClass));  
  6. // To read the file, create a FileStream.  
  7. FileStream myFileStream =   
  8. new FileStream("myFileName.xml", FileMode.Open);  
  9. // Call the Deserialize method and cast to the object type.  
  10. myObject = (MySerializableClass)   
  11. mySerializer.Deserialize(myFileStream) 

 

2,二进制序列化

XML序列化只能序列化公共属性和字段。属性必须具有公共访问器(get 和 set 方法)。如果必须序列化非公共数据,请使用 BinaryFormatter 类而不是 XML 序列化。

使类可序列化的最简单方法是按以下方式使用 Serializable 属性对其进行标记。

 
  
  1. [Serializable]  
  2. public class MyObject {  
  3.   public int n1 = 0;  
  4.   public int n2 = 0;  
  5.   public String str = null;  

(1)序列化对象

 
  
  1. MyObject obj = new MyObject();  
  2. obj.n1 = 1;  
  3. obj.n2 = 24;  
  4. obj.str = "Some String";  
  5. IFormatter formatter = new BinaryFormatter();  
  6. Stream stream = new FileStream("MyFile.bin", FileMode.Create, FileAccess.Write, FileShare.None);  
  7. formatter.Serialize(stream, obj);  
  8. stream.Close(); 

 

(2)反序列化对象

 
  
  1. IFormatter formatter = new BinaryFormatter();  
  2. Stream stream = new FileStream("MyFile.bin", FileMode.Open, FileAccess.Read, FileShare.Read);  
  3. MyObject obj = (MyObject) formatter.Deserialize(stream);  
  4. stream.Close();  
  5.  
  6. // Here's the proof.  
  7. Console.WriteLine("n1: {0}", obj.n1);  
  8. Console.WriteLine("n2: {0}", obj.n2);  
  9. Console.WriteLine("str: {0}", obj.str); 

<注意>

1,无法继承 Serializable 属性。如果从 MyObject 派生新类,新类也必须标记为以上属性,否则将无法序列化。(实验表示,使用XML序列化时,类未标记[Serializable]也可以序列化)。

2,类通常包含不应进行序列化的字段。例如,假定类将线程 ID 存储在成员变量中。如果反序列化该类,而在对该类进行序列化时,存储了该 ID 的线程可能不再运行。因此,序列化该值毫无意义。您可以防止对成员变量进行序列化,方法是使用 NonSerialized 属性标记它们,如下所述。

 
  
  1. [Serializable]  
  2. public class MyObject   
  3. {  
  4.   public int n1;  
  5.   [NonSerialized] public int n2;  
  6.   public String str;  

如有可能,应使可能包含安全敏感数据的对象不可序列化。如果必须对该对象进行序列化,可将 NonSerialized 属性应用于存储敏感数据的特定字段。