序列化是将对象状态转换为可保持或传输的格式的过程。与序列化相对的是反序列化,它将流转换为对象。两个过程结合可以存储和传输数据。
.NET Framework提供两种序列化技术。
(1)二进制序列化:可以保持类型不变,即可以在应用程序的不同调用之间保留对象的状态。
(2)XML和SOAP序列化:仅序列化公共属性和字段,不保存类型。
二进制序列化:
序列化可被定义为将对象的状态存储到存储媒介中的过程。在此过程中,对象的公共字段和私有字段以及类的名称(包括包含该类的程序集)都被转换为字节流,然后写入数据流。在以后反序列化该对象时,创建原始对象的精确复本。
序列化有两个重要的功能:一个是将对象的状态保持在存储媒体中,以便在以后可以重新创建精确的副本;另一个是通过值将对象从一个应用程序域发送到另一个应用程序域中。例如,序列化可用于在ASP.NET中保存会话状态并将对象复制到Windows窗体的程序域中。
1.序列化
序列化一个类的最简单的方式是使用如下所示的Serializable属性标记。
![](https://i-blog.csdnimg.cn/blog_migrate/cdec0645add3fc3c328197dda5c76203.gif)
1 [Serializable]
2 public class AuthUserEntry
3 {
4 private string accountName;
5 private int accountId;
6 private string AccountName
7 {
8 ...
9 }
10 public int AccountId
11 {
12 ...
13 }
14 }
15
下面用代码演示了该类的实例是如何被序列化到一个二进制文件(.bin)中的。
![](https://i-blog.csdnimg.cn/blog_migrate/cdec0645add3fc3c328197dda5c76203.gif)
1 AuthUserEntry user=new AuthUserEntry();
2 user.AccountId=8712590 ;
3 user.AccountName="admin" ;
4 IFormatter formater=new BinaryFormatter();
5 Stream stream=new FileStream("UserInfo.bin" ,FileMode.Create,FileAccess.Write,FileShare.None);
6 formater.Serialize(stream,user);
7 stream.Close();
在这段代码中,创建流的实例和使用的格式接口后,对该格式接口调用Serialize方法,类中的所有成员变量都将被序列化,即使是那些已被标记为私有的变量。
2.反序列化
要将对象还原回其以前的状态,首先,创建用于读取的流和格式化接口,然后再用格式化接口反序列化该对象。下面的代码示例说明如何执行上述的操作。
![](https://i-blog.csdnimg.cn/blog_migrate/cdec0645add3fc3c328197dda5c76203.gif)
1 IFormatter formater=new BinaryFormatter();
2 Stream stream=new FileStream("UserInfo.bin" ,FileMode.Open,FileAccess.Read,FileShare.Read);
3 AuthUserEntry me= (AuthUserEntry) formater.Deserialize(stream);
4 stream.Close();
5
需要特别注意的是,在反序列化一个对象时不调用构造函数。
3.有选择的序列化
也可能在类中包含不应被序列化的字段。例如,假设一个类将线程ID存储在成员变量中。当反序列化该类时,在序列化该类时为其存储ID的线程可能不再运行,因此序列化该值没有意义。通过用NonSerialized属性标记成员变量,可以防止它们被序列化,如下所示:
1 [Serializable]
2 public class MyObject
3 {
4 public int n1;
5 [NonSerialized] public int n2;
6 public String str;
7 }
8
XML和SOAP序列化与反序列化:
也可以对XML和SOAP流对象进行序列化和反序列化,这种操作一般用于将对象转换为网络中容易传输的格式。例如,可以序列化一个对象,然后使用HTTP通过Internet在客户端和服务器之间传输该对象;在另一端,通过反序列化重新构造对象。
XML序列化仅将对象的公共字段和属性值序列化为XML流,而不转换方法、索引器、私有字段或只读属性(只读集合除外)。若要序列化对象的所有字段和属性(公共的和私有的),可以使用BinaryFormatter序列化。XML序列化不包括类型信息,即不能保证序列化后的对象在被反序列化时,变为同一类型的对象。
XML序列化中最主要的类是XmlSerializer类,它的最重要的方法是Serialize和Deserialize。XmlSerializer生成的XML流符合万维网联合会(www.w3.org)XML架构定义语言(XSD)的建议。
使用XmlSerializer类,可将下列各项序列化。
1、序列化对象
首先,创建要序列化的对象并设置它的公共属性和字段,而且必须确定用以存储XML流的传输格式(或者作为流,或者作为文件)。例如,如果XML流必须以永久形式保存,则创建FileStream对象。当反序列化对象时,传输格式将确定创建流还是文件对象。确定了传输格式之后,就可以根据需要调用Serialize或Deserialize方法。
其次,调用该对象的类型构造XmlSerialize方法。
最后,调用Serialize方法以生成对象的公共属性和字段的XML流表示形式或文件表示形式。
下面事例是创建一个对象:
![](https://i-blog.csdnimg.cn/blog_migrate/cdec0645add3fc3c328197dda5c76203.gif)
1 //第一步,创建要序列化的对象
2 AuthUserEntry user=new AuthUserEntry();
3 user.AccountId=8712590 ;
4 user.AccountName="admin" ;
5 //第二步,构造XmlSeriaLizer对象
6 XmlSerializer mySerializer=new XmlSerializer(typeof (AuthUserEntry));
7 //创建Stream Writer对象完成对文件的写操作
8 StreamWriter myWriter=new StreamWriter("UserInfo.xml" );
9 //第三步,调用Serialize方法实现序列化
10 mySerializer.Serialize(myWriter,user);
11 myWriter.Close();
12
2、反序列化对象
首先,使用要反序列化的对象的类型构造XmlSerializer。
其次,调用Deserialize方法以产生该对象的副本。在反序列化时,必须将返回的对象强制转换为原始对象的类型。
将对象反序列化为文件的语句为:
![](https://i-blog.csdnimg.cn/blog_migrate/cdec0645add3fc3c328197dda5c76203.gif)
1 AuthUserEntry me;
2 //用对象类型构造XmlSerializer的实例
3 XmlSerializer mySerializer=new XmlSerializer(typeof (AuthUserEntry));
4 //创建FileStream读取文件
5 FileStream myFileStream=new FileStream("UserInfo.xml" ,FileMode.Open);
6 //调用Deserialize方法并强制转换返回对象的类型
7 me= (AuthUserEntry) mySerializer.Deserialize(myFileStream);
8 myFileStream.Close();
9
例子:Xml序列化和反序列化的方法
![](https://i-blog.csdnimg.cn/blog_migrate/cdec0645add3fc3c328197dda5c76203.gif)
1 using System;
2 using System.IO;
3 using System.Xml.Serialization;
4 namespace XMLSerializableExample
5 {
6 [Serializable]
7 public class AuthUserEntry
8 {
9 private string accountName;
10 private int accountId;
11 public string AccountName
12 {
13 get
14 {
15 return accountName;
16 }
17 set
18 {
19 accountName= value;
20 }
21 }
22 public int AccountId
23 {
24 get
25 {
26 return accountId;
27 }
28 set
29 {
30 accountId= value;
31 }
32 }
33 }
34 class Account
35 {
36 static void Main(string [] args)
37 {
38 //第一步,创建要序列化的对象
39 AuthUserEntry user=new AuthUserEntry();
40 user.AccountId=8712590 ;
41 user.AccountName="admin" ;
42 //第二步,构造XmlSeriaLizer对象
43 XmlSerializer mySerializer=new XmlSerializer(typeof (AuthUserEntry));
44 //创建Stream Writer对象完成对文件的写操作
45 StreamWriter myWriter=new StreamWriter("UserInfo.xml" );
46 //第三步,调用Serialize方法实现序列化
47 mySerializer.Serialize(myWriter,user);
48 myWriter.Close();
49 AuthUserEntry me;
50 //创建FileStream读取文件
51 FileStream myFileStream=new FileStream("UserInfo.xml" ,FileMode.Open);
52 //调用Deserialize方法并强制转换返回对象的类型
53 me= (AuthUserEntry) mySerializer.Deserialize(myFileStream);
54 myFileStream.Close();
55 Console.WriteLine("帐户号:{0}" ,me.AccountId);
56 Console.WriteLine("帐户名:{0}" ,me.AccountName);
57 //按回车键结束
58 Console.ReadLine();
59 }
60 }
61 }
62
打开应用程序bin文件夹中的Debug文件夹,会看到有一个生成文件UserInfo.xml,用VS2005打开它,会看到正是AuthUserEntry对象实例的值。