Mcad学习笔记之序列化(2进制和Soap序列化)
我最近学习remoting和web服务时,总是看到一个重要的字眼"序列化".
那什么是序列化呢?以前我也模模糊糊.
为了搞清楚,请和我一起来序列化学习之旅吧.
让我们先看看序列化的定义,以下是微软的说明:
序列化可被定义为将对象的状态存储到存储媒介中的过程。在此过程中,对象的公共字段和私有字段以及类的名称(包括包含该类的程序集)都被转换为字节流,然后写入数据流。在以后反序列化该对象时,创建原始对象的精确复本
序列化一般用在2种地方:
1.将数据保持到存储中
例如:我知道在Asp.Net Forums中有.Net中序列化和反序列化的应用
在Forums中,有些内容是不固定的,如用户资料,除了一些基本资料,可能还要MSN、个人主页、签名等.我们一般是一个属性对应于表中的一个字段,要是以后我们增加一些新属性,就得增加表字段,还要修改存储过程,这样其不麻烦?
在Asp.Net Forums中把用户资料序列化为2进制,这样用一个表字段就可以解决问题,并且扩展性好。
2.通过值将对象从一个应用程序域发送到另一个应用程序域中
remoting和web服务就是典型的应用
说多了没用,让我们来一段代码吧
先定义一个类
1
using System;
2![](/Images/OutliningIndicators/None.gif)
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![](/Images/OutliningIndicators/InBlock.gif)
18
public int Account
19
{
20
get
21
{
22
return account;
23
}
24
}
25![](/Images/OutliningIndicators/InBlock.gif)
26
public string Name
27
{
28
get
29
{
30
return name;
31
}
32
}
33
}
34
}
35![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
2
![](/Images/OutliningIndicators/None.gif)
3
![](/Images/OutliningIndicators/None.gif)
4
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
5
![](/Images/OutliningIndicators/InBlock.gif)
6
![](/Images/OutliningIndicators/InBlock.gif)
7
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
8
![](/Images/OutliningIndicators/InBlock.gif)
9
![](/Images/OutliningIndicators/InBlock.gif)
10
![](/Images/OutliningIndicators/InBlock.gif)
11
![](/Images/OutliningIndicators/InBlock.gif)
12
![](/Images/OutliningIndicators/InBlock.gif)
13
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
14
![](/Images/OutliningIndicators/InBlock.gif)
15
![](/Images/OutliningIndicators/InBlock.gif)
16
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
17
![](/Images/OutliningIndicators/InBlock.gif)
18
![](/Images/OutliningIndicators/InBlock.gif)
19
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
20
![](/Images/OutliningIndicators/InBlock.gif)
21
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
22
![](/Images/OutliningIndicators/InBlock.gif)
23
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
24
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
25
![](/Images/OutliningIndicators/InBlock.gif)
26
![](/Images/OutliningIndicators/InBlock.gif)
27
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
28
![](/Images/OutliningIndicators/InBlock.gif)
29
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
30
![](/Images/OutliningIndicators/InBlock.gif)
31
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
32
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
33
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
34
![](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
35
![](/Images/OutliningIndicators/None.gif)
序列化一个类的最简单的方式是使用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![](/Images/OutliningIndicators/None.gif)
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![](/Images/OutliningIndicators/InBlock.gif)
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![](/Images/OutliningIndicators/InBlock.gif)
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![](/Images/OutliningIndicators/InBlock.gif)
30
Console.WriteLine("c2的名字="+ c2.Name );
31
Console.WriteLine("c2的账号="+ c2.Account.ToString() );
32![](/Images/OutliningIndicators/InBlock.gif)
33
Console.ReadLine();
34
}
35
}
36
}
![](/Images/OutliningIndicators/None.gif)
2
![](/Images/OutliningIndicators/None.gif)
3
![](/Images/OutliningIndicators/None.gif)
4
![](/Images/OutliningIndicators/None.gif)
5
![](/Images/OutliningIndicators/None.gif)
6
![](/Images/OutliningIndicators/None.gif)
7
![](/Images/OutliningIndicators/None.gif)
8
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
9
![](/Images/OutliningIndicators/InBlock.gif)
10
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
11
![](/Images/OutliningIndicators/InBlock.gif)
12
![](/Images/OutliningIndicators/InBlock.gif)
13
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
14
![](/Images/OutliningIndicators/InBlock.gif)
15
![](/Images/OutliningIndicators/InBlock.gif)
16
![](/Images/OutliningIndicators/InBlock.gif)
17
![](/Images/OutliningIndicators/InBlock.gif)
18
![](/Images/OutliningIndicators/InBlock.gif)
19
![](/Images/OutliningIndicators/InBlock.gif)
20
![](/Images/OutliningIndicators/InBlock.gif)
21
![](/Images/OutliningIndicators/InBlock.gif)
22
![](/Images/OutliningIndicators/InBlock.gif)
23
![](/Images/OutliningIndicators/InBlock.gif)
24
![](/Images/OutliningIndicators/InBlock.gif)
25
![](/Images/OutliningIndicators/InBlock.gif)
26
![](/Images/OutliningIndicators/InBlock.gif)
27
![](/Images/OutliningIndicators/InBlock.gif)
28
![](/Images/OutliningIndicators/InBlock.gif)
29
![](/Images/OutliningIndicators/InBlock.gif)
30
![](/Images/OutliningIndicators/InBlock.gif)
31
![](/Images/OutliningIndicators/InBlock.gif)
32
![](/Images/OutliningIndicators/InBlock.gif)
33
![](/Images/OutliningIndicators/InBlock.gif)
34
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
35
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
36
![](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
![](https://images.cnblogs.com/cnblogs_com/aierong/SerializTest1.gif)
我们可以看到由于类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![](/Images/OutliningIndicators/None.gif)
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![](/Images/OutliningIndicators/InBlock.gif)
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![](/Images/OutliningIndicators/InBlock.gif)
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![](/Images/OutliningIndicators/InBlock.gif)
49
Console.ReadLine();
50
}
51
}
52
}
![](/Images/OutliningIndicators/None.gif)
2
![](/Images/OutliningIndicators/None.gif)
3
![](/Images/OutliningIndicators/None.gif)
4
![](/Images/OutliningIndicators/None.gif)
5
![](/Images/OutliningIndicators/None.gif)
6
![](/Images/OutliningIndicators/None.gif)
7
![](/Images/OutliningIndicators/None.gif)
8
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
9
![](/Images/OutliningIndicators/InBlock.gif)
10
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
11
![](/Images/OutliningIndicators/InBlock.gif)
12
![](/Images/OutliningIndicators/InBlock.gif)
13
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
14
![](/Images/OutliningIndicators/InBlock.gif)
15
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
16
![](/Images/OutliningIndicators/InBlock.gif)
17
![](/Images/OutliningIndicators/InBlock.gif)
18
![](/Images/OutliningIndicators/InBlock.gif)
19
![](/Images/OutliningIndicators/InBlock.gif)
20
![](/Images/OutliningIndicators/InBlock.gif)
21
![](/Images/OutliningIndicators/InBlock.gif)
22
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
23
![](/Images/OutliningIndicators/InBlock.gif)
24
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
25
![](/Images/OutliningIndicators/InBlock.gif)
26
![](/Images/OutliningIndicators/InBlock.gif)
27
![](/Images/OutliningIndicators/InBlock.gif)
28
![](/Images/OutliningIndicators/InBlock.gif)
29
![](/Images/OutliningIndicators/InBlock.gif)
30
![](/Images/OutliningIndicators/InBlock.gif)
31
![](/Images/OutliningIndicators/InBlock.gif)
32
![](/Images/OutliningIndicators/InBlock.gif)
33
![](/Images/OutliningIndicators/InBlock.gif)
34
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
35
![](/Images/OutliningIndicators/InBlock.gif)
36
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
37
![](/Images/OutliningIndicators/InBlock.gif)
38
![](/Images/OutliningIndicators/InBlock.gif)
39
![](/Images/OutliningIndicators/InBlock.gif)
40
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
41
![](/Images/OutliningIndicators/InBlock.gif)
42
![](/Images/OutliningIndicators/InBlock.gif)
43
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
44
![](/Images/OutliningIndicators/InBlock.gif)
45
![](/Images/OutliningIndicators/InBlock.gif)
46
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
47
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
48
![](/Images/OutliningIndicators/InBlock.gif)
49
![](/Images/OutliningIndicators/InBlock.gif)
50
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
51
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
52
![](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
![](https://images.cnblogs.com/cnblogs_com/aierong/SerializTest2.gif)
其实数组也是可以序列化的类
那么我们可以把上面的代码做些简化
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![](/Images/OutliningIndicators/None.gif)
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![](/Images/OutliningIndicators/InBlock.gif)
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![](/Images/OutliningIndicators/InBlock.gif)
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![](/Images/OutliningIndicators/InBlock.gif)
35
Console.ReadLine();
36
}
37
}
38
}
![](/Images/OutliningIndicators/None.gif)
2
![](/Images/OutliningIndicators/None.gif)
3
![](/Images/OutliningIndicators/None.gif)
4
![](/Images/OutliningIndicators/None.gif)
5
![](/Images/OutliningIndicators/None.gif)
6
![](/Images/OutliningIndicators/None.gif)
7
![](/Images/OutliningIndicators/None.gif)
8
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
9
![](/Images/OutliningIndicators/InBlock.gif)
10
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
11
![](/Images/OutliningIndicators/InBlock.gif)
12
![](/Images/OutliningIndicators/InBlock.gif)
13
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
14
![](/Images/OutliningIndicators/InBlock.gif)
15
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
16
![](/Images/OutliningIndicators/InBlock.gif)
17
![](/Images/OutliningIndicators/InBlock.gif)
18
![](/Images/OutliningIndicators/InBlock.gif)
19
![](/Images/OutliningIndicators/InBlock.gif)
20
![](/Images/OutliningIndicators/InBlock.gif)
21
![](/Images/OutliningIndicators/InBlock.gif)
22
![](/Images/OutliningIndicators/InBlock.gif)
23
![](/Images/OutliningIndicators/InBlock.gif)
24
![](/Images/OutliningIndicators/InBlock.gif)
25
![](/Images/OutliningIndicators/InBlock.gif)
26
![](/Images/OutliningIndicators/InBlock.gif)
27
![](/Images/OutliningIndicators/InBlock.gif)
28
![](/Images/OutliningIndicators/InBlock.gif)
29
![](/Images/OutliningIndicators/InBlock.gif)
30
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
31
![](/Images/OutliningIndicators/InBlock.gif)
32
![](/Images/OutliningIndicators/InBlock.gif)
33
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
34
![](/Images/OutliningIndicators/InBlock.gif)
35
![](/Images/OutliningIndicators/InBlock.gif)
36
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
37
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
38
![](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
代码简化了不少,功能是一样的
小总结:
我上面的代码全部是利用了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派生一个新类,此新类必须也用该属性标记,否则它不能被序列化.
希望上面提到的知识对你有所提示
当然欢迎交流和指正
收藏与分享
RSS订阅我 什么是RSS?
东莞.net俱乐部
我的系列文章
A.Sql Server2005 Transact-SQL 新兵器学习 B.MCAD学习
C.代码阅读总结
D.ASP.NET状态管理
E.DB(数据库)
F.WAP
G.WinForm
H.Flex
希望上面提到的知识对您有所提示,同时欢迎交流和指正
作者:aierong
出处:http://www.cnblogs.com/aierong
贴子以"现状"提供且没有任何担保,同时也没有授予任何权利!
本文版权归作者所有,欢迎转载!
原创技术文章和心得,转载注明出处!这也是对原创者的尊重!