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

相关文章导航
Sql Server2005 Transact-SQL 新兵器学习总结之-总结
Flex,Fms3相关文章索引
FlexAir开源版-全球免费多人视频聊天室,免费网络远程多人视频会议系统((Flex,Fms3联合开发))<视频聊天,会议开发实例8>
我最近学习remoting和web服务时,总是看到一个重要的字眼"序列化".
那什么是序列化呢?以前我也模模糊糊.
 
为了搞清楚,请和我一起来序列化学习之旅吧.
 
让我们先看看序列化的定义,以下是微软的说明:
序列化可被定义为将对象的状态存储到存储媒介中的过程。在此过程中,对象的公共字段和私有字段以及类的名称(包括包含该类的程序集)都被转换为字节流,然后写入数据流。在以后反序列化该对象时,创建原始对象的精确复本
 
序列化一般用在2种地方:
1.将数据保持到存储中
例如:我知道在Asp.Net Forums中有.Net中序列化和反序列化的应用
在Forums中,有些内容是不固定的,如用户资料,除了一些基本资料,可能还要MSN、个人主页、签名等.我们一般是一个属性对应于表中的一个字段,要是以后我们增加一些新属性,就得增加表字段,还要修改存储过程,这样其不麻烦?
在Asp.Net Forums中把用户资料序列化为2进制,这样用一个表字段就可以解决问题,并且扩展性好。
 
2.通过值将对象从一个应用程序域发送到另一个应用程序域中
remoting和web服务就是典型的应用
 
说多了没用,让我们来一段代码吧
先定义一个类
 1using System;
 2
 3namespace 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属性只可以用在类的某个字段上

好了,再来一段俺喜欢的控制台来看看到底是怎么回事
 1using System;
 2using System.IO;
 3using System.Runtime.Serialization;
 4using System.Runtime.Serialization.Formatters.Binary;
 5using System.Runtime.Serialization.Formatters.Soap;
 6
 7namespace 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类实例的账号,只能看到名字

让我们再看一段,同时序列化多个对象的代码
 1using System;
 2using System.IO;
 3using System.Runtime.Serialization;
 4using System.Runtime.Serialization.Formatters.Binary;
 5using System.Runtime.Serialization.Formatters.Soap;
 6
 7namespace 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=o 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}
结果是


其实数组也是可以序列化的类
那么我们可以把上面的代码做些简化
 1using System;
 2using System.IO;
 3using System.Runtime.Serialization;
 4using System.Runtime.Serialization.Formatters.Binary;
 5using System.Runtime.Serialization.Formatters.Soap;
 6
 7namespace 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            IFormatter formatter=new BinaryFormatter();
19            Stream stream = new FileStream(fileName, FileMode.Create, FileAccess.Write,FileShare.None);
20            formatter.Serialize(stream,myClass);
21            stream.Close();
22
23            //反序列化过程开始
24            IFormatter formatter11=new  BinaryFormatter();
25            Stream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read,FileShare.Read);
26            Class2[] list=(Class2[])formatter11.Deserialize(fs);
27            fs.Close();
28            Console.WriteLine("反序列化结果:");
29            foreach(Class2 o in list)
30            {
31                Console.WriteLine("名字="+ o.Name );
32                Console.WriteLine("账号="+ o.Account.ToString());
33            }
34
35            Console.ReadLine();
36        }
37    }
38}
代码简化了不少,功能是一样的

小总结:
我上面的代码全部是利用了BinaryFormatter类来进行序列化
此类序列化对于在 .NET 平台上进行运用效果比较理想
要是考虑到程序的可移植性,我们可以考虑用类SoapFormatter替代
同样也是调用Serialize和Deserialize方法
因为这2个类都实行了接口IFormatter
特别注意的是,Serializable属性不能被继承.
由SerializableAttribute类的定义我们可以看出.
[AttributeUsage(AttributeTargets.Delegate | (AttributeTargets.Enum | (AttributeTargets.Struct | AttributeTargets.Class)), Inherited=false)]
public sealed class SerializableAttribute : Attribute
如果我们从Class2派生一个新类,此新类必须也用该属性标记,否则它不能被序列化.

希望上面提到的知识对你有所提示
当然欢迎交流和指正
 
收藏与分享
收藏到QQ书签 添加到百度搜藏 添加到百度搜藏 添加到雅虎收藏 分享到饭否 收藏到就喜欢网络收藏夹 

RSS订阅我 什么是RSS?
feedsky    http://wap.feedsky.com/aierongrss    E-mail 
订阅到雅蛙        使用RSS邮天下订阅    订阅到有道阅读 
订阅到抓虾    鲜果阅读器订阅图标    Add to Google 
訂閱 Bloglines    哪吒提醒    Subscribe in NewsGator Online

东莞.net俱乐部
东莞.net俱乐部 欢迎您的加入

我的系列文章
A.Sql Server2005 Transact-SQL 新兵器学习 
B.MCAD学习 
C.代码阅读总结 
D.ASP.NET状态管理 
E.DB(数据库) 
F.WAP 
G.WinForm 
H.Flex

我的好文推荐
FlexAir开源版-全球免费多人视频聊天室,免费网络远程多人视频会议系统((Flex,Fms3联合开发))<视频聊天,会议开发实例8> 
Sql Server2005 Transact-SQL 新兵器学习总结之-总结 
MS SQL数据库备份和恢复存储过程(加强版本) 
sql server中分布式查询随笔(链接服务器(sp_addlinkedserver)和远程登录映射(sp_addlinkedsrvlogin)使用小总结) 
ASP.NET2.0国际化/本地化应用程序的实现总结(多语言,多文化页面的实现) 
WAP开发资料站(最新更新) 
自定义格式字符串随笔 (IFormattable,IFormatProvider,ICustomFormatter三接口的实现) 
Mcad学习笔记之异步编程(AsyncCallback 委托,IAsyncResult接口,BeginInvoke方法,EndInvoke方法的使用小总结) 
Mcad学习笔记之通过反射调用類的方法,屬性,字段,索引器(2種方法) 
Mcad学习笔记之序列化(2进制和Soap序列 化) 
Mcad学习笔记之委托再理解(delegate的构造器,BeginInvoke,EndInvoke,Invoke4个方法的探讨) 
ASP.NET状态管理之一(概括篇) 
Flex,Fms学习笔记

banner




本文转自aierong博客园博客,原文链接:http://www.cnblogs.com/aierong/archive/2005/05/29/164501.html,如需转载请自行联系原作者
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值