对象通常都有状态(state), 例如一个class 的某个实体可以有一个或多个fields, 每一个都包含某个值。从一个对象中抽取这种状态, 不论是将它存储于某地, 亦或通过网络传送它, 通常都是有意义的。这种抽取动作称为“将一个对象序列化(serializing)”而反向处理过程, 从一个被序列化的状态重建一个对象, 即是广为人知的反序列化(deserializing)。.NET Framework 提供了两种不同的序列化技术
1) 二进制序列化
二进制序列化是接受一种复杂数据类型(或对象), 并将其编码为一个二进制流、更改为永久状态、传输然后解码(反序列化)回原始复杂数据类型的过程。二进制序列化能保持类型精度, 通常用于在应用程序的不同调用间保存对象状态。例如, 同一对象可以通过剪贴板序列化由不同应用程序共享。对象可以被序列化到流、磁盘、内存、网络等。远程操作通过序列化, 在计算机或应用程序域间传递对象值。
2)XML 序列化
XML 序列化是将对象的公共字段和属性(或者方法)的参数及回值序列化为符合特定XML 架构定义语言(XSD) 文档的XML 流的过程。XML 序列化只用于保存公共属性和字段, 但无法保持类型精度。这种序列化适用于保存对使用数据的应用程序无限制的数据。由于XML 是一种开放式规范, 因此是web 数据共享的理想选择。
二进制序列化的实现
1) 添加所需的命名空间
using System.Runtime.Serialization
using System.Runtime.Serialization.Formatters.Binary
[Serializable]
public class Car
{
public string CarNum;
public double CarLength;
public double CarHeight;
private string CarColor;
}
3) 实例类, 创建流实例
Car car1=new Car();
car1.CarNum=”A0137”;
car1.CarLength=4.6;
car1.CarHeigth=1.5
car1.CarColor=”Red”;
Stream stream=new FileStream (“FileStream.bin”,FileMode.Creat,FileAccess.Write,
FileShare.None);
4) 选择格式器, 序列化
BinaryFormatter formatter=new BinaryFormatter();
formatter.Serialize(stream,formatter);
stream.Close();
二进制反序列化的实现
1) 创建格式化程序的实例和流以进行读取
BinaryFormatter formatter=new BinaryFormatter();
Stream stream=
new FileStream (“FileStream.bin”,FileMode.Open,FileAccess.Read,
FileShare.None);
Car car2=formatter.Deserialize(stream);
stream.Close();
Console.WriteLine(“car2.CarNum:{0}”,car2.CarNum);
Console.WriteLine(“car2.CarLength:{0}”,car2.CarLength);
Console.WriteLine(“car2.CarHeight:{0}”,car2.CarHeight);
Console.WriteLine(“car2.CarColor:{0}”,car2.Color);
这里使用流打开FielSteam.bin 文件,这个stream 被传入二进制格式器的Deseralize( )中, 运行结果赋予car2。尽管car2 只具缺省状态,但反序列化过程给予了它早先从car1 萃取而来的状态。因而输出结果是:
car2.CarNum:A0137
car2.CarLength:4.6
car2.CarHeight:1.5
car2.CarColor:Red
注意的是, 对对象进行反序列化时并不调用构造函数。对反序列化添加这项约束, 是出于性能方面的考虑。但是, 这违反了对象编写者通常采用的一些运行时约定, 因此, 开发人员在将对象标记为可序列化时, 应确保考虑了这一特殊约定。
二进制序列化的安全问题
当将对象序列化成为流时, 这个流中既包含了对象的公有数据,也包含了对象的私有数据。如果私有数据是敏感数据, 应该对流进行特殊的处理。
NET 提供的两个类都不具有数据保密的功能。即使是BinaryFormatter, 也没有数据加密的功能, 所以, 也可以从BinaryFormatter 或者SoapFormatter 中序列化过的对象进行反序列化,并读取出来, 因此, 在传递序列化对象或者保存序列化对象时, 必须注意一些敏感信息, 因为他们需要被有保护地保存, 这就是安全方面的隐患。
对于一些机密数据, 在进行序列化之前, 最好先通过某种手段保证数据在网络上传递或者保存时的安全性, 比如, 可以自定义一些加密方式和序列化过程, 以保证序列化的数据是经过加密的, 或者在网络传输过程中通过一些加密方式以防明文数据被截取。这是在序列化的过程中所需要执行的额外操作。