Mcad学习笔记之序列化(2进制和Soap序列化)

系统 1925 0
我最近学习remoting和web服务时,总是看到一个重要的字眼"序列化".
那什么是序列化呢?
以前我也模模糊糊.
 
为了搞清楚,请和我一起来序列化学习之旅吧.
 
让我们先看看序列化的定义,以下是微软的说明:
序列化可被定义为将对象的状态存储到存储媒介中的过程。在此过程中,对象的公共字段和私有字段以及类的名称(包括包含该类的程序集)都被转换为字节流,然后写入数据流。在以后反序列化该对象时,创建原始对象的精确复本
 
序列化一般用在2种地方:
1.将数据保持到存储中
例如:我知道在Asp.Net Forums中有.Net中序列化和反序列化的应用
在Forums中,有些内容是不固定的,如用户资料,除了一些基本资料,可能还要MSN、个人主页、签名等.我们一般是一个属性对应于表中的一个字段,要是以后我们增加一些新属性,就得增加表字段,还要修改存储过程,这样其不麻烦?
在Asp.Net Forums中把用户资料序列化为2进制,这样用一个表字段就可以解决问题,并且扩展性好。
 
2.通过值将对象从一个应用程序域发送到另一个应用程序域中
remoting和web服务就是典型的应用
 
说多了没用,让我们来一段代码吧
先定义一个类
 1 using  System;
 2
 3 namespace  SerializTest
 4 {
 5     [Serializable]
 6      public   class  Class2
 7      {
 8          private   string  name;
 9         [NonSerialized]
10          private   int  account;
11         
12          public  Class2( string  name, int  account)
13          {
14              this .account = account;
15              this .name = name;
16         }

17
18          public   int  Account
19          {
20              get
21              {
22                  return  account;
23             }

24         }

25
26          public   string  Name
27          {
28              get
29              {
30                  return  name;
31             }

32         }

33     }

34 }

35
说明:
序列化一个类的最简单的方式是使用Serializable属性
当然还可以通过在对象上实现ISerializable接口,自定义序列化
标记了Serializable属性的类,类里面的所有成员都将被序列化,私有的变量也在内
当然我们也可以有选择的序列化类里面的字段
例如类里面的一些敏感数据,我们可以不对其进行序列化
通过用NonSerialized属性标记成员变量,可以防止它们被序列化
NonSerialized属性只可以用在类的某个字段上

好了,再来一段俺喜欢的控制台来看看到底是怎么回事
 1 using  System;
 2 using  System.IO;
 3 using  System.Runtime.Serialization;
 4 using  System.Runtime.Serialization.Formatters.Binary;
 5 using  System.Runtime.Serialization.Formatters.Soap;
 6
 7 namespace  SerializTest
 8 {
 9      class  Class1
10      {
11         [STAThread]
12          static   void  Main( string [] args)
13          {
14              string  fileName = " MyFile.dat " ;
15             Class2 my = new  Class2( " Serializ TestSerializ " , 987 ); 
16             Console.WriteLine( " 初始化Class2类的一个实例my,my的账号=987,my的名字=Serializ TestSerializ " );
17
18              // 序列化过程开始,我们把Class2的实例二进制序列化到文件MyFile.dat中
19             IFormatter formatter1 = new   BinaryFormatter();
20             Stream stream1  =   new  FileStream(fileName, FileMode.Create, FileAccess.Write,FileShare.None);
21             formatter1.Serialize(stream1,my);
22             stream1 .Close();
23
24              // 反序列化过程开始,我们把Class2的实例从文件MyFile.dat中取出来
25             IFormatter formatter  =   new  BinaryFormatter();
26             Stream stream  =   new  FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
27             Class2 c2  =  (Class2) formatter.Deserialize(stream);
28             stream.Close();
29
30             Console.WriteLine( " c2的名字= " +  c2.Name );
31             Console.WriteLine( " c2的账号= " +  c2.Account.ToString() );
32
33             Console.ReadLine();
34         }

35     }

36 }
结果是

我们可以看到由于类Class2的account字段运用了NonSerialized属性
反序列化后我们是看不到Class2类实例的账号,只能看到名字

让我们再看一段,同时序列化多个对象的代码
 1 using  System;
 2 using  System.IO;
 3 using  System.Runtime.Serialization;
 4 using  System.Runtime.Serialization.Formatters.Binary;
 5 using  System.Runtime.Serialization.Formatters.Soap;
 6
 7 namespace  SerializTest
 8 {
 9      class  Class1
10      {
11         [STAThread]
12          static   void  Main( string [] args)
13          {
14              string  fileName = " MyFile.dat " ;
15             Class2[] myClass = { new  Class2( " a " , 123 ), new  Class2( " b " , 456 ), new  Class2( " c " , 789 )} ;
16
17              // 序列化过程开始
18              // 我们把类的几个实例序列化到一个文件中,这样比起分别序列化可以节约空间
19             IFormatter formatter = new  BinaryFormatter();
20             Stream stream  =   new  FileStream(fileName, FileMode.Create, FileAccess.Write,FileShare.None);
21              for ( int  i = 0 ;i < myClass.Length;i ++ )
22              {
23                 formatter.Serialize(stream,myClass[i]);
24             }

25             stream.Close();
26
27              // 反序列化过程开始
28             IFormatter formatter11 = new   BinaryFormatter();
29             Stream fs  =   new  FileStream(fileName, FileMode.Open, FileAccess.Read,FileShare.Read);
30              long  ii =  fs.Length;
31             System.Collections.ArrayList list = new  System.Collections.ArrayList();
32              // 从文件中逐个读出Class2的实例并反序列化
33              while  (fs.Position != fs.Length)
34              {
35                 list.Add(formatter11.Deserialize(fs));
36             }

37             fs.Close();
38             Console.WriteLine( " 反序列化结果: " );
39              foreach ( object  o  in  list)
40              {
41                 Class2 class2 = as  Class2;
42                  if  (class2 != null )
43                  {
44                     Console.WriteLine( " 名字= " +  class2.Name );
45                     Console.WriteLine( " 账号= " +  class2.Account.ToString());
46                 }

47             }

48
49             Console.ReadLine();
50         }

51     }

52 }
结果是


其实数组也是可以序列化的类
那么我们可以把上面的代码做些简化
 1 using  System;
 2 using  System.IO;
 3 using  System.Runtime.Serialization;
 4 using  System.Runtime.Serialization.Formatters.Binary;
 5 using  System.Runtime.Serialization.Formatters.Soap;
 6
 7 namespace  SerializTest
 8 {
 9      class  Class1
10      {
11         [STAThread]
12          static   void  Main( string [] args)
13          {
14            

Mcad学习笔记之序列化(2进制和Soap序列化)


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论