对象的序列化主要解决的是对象状态的保存问题。这里所说的“对象状态”,其实就是指某一时刻对象所拥有的各个字段值的集合。
序列化最主要的作用有:
1、在进程下次启动时读取上次保存的对象的信息
2、在不同的AppDomain或进程之间传递数据
3、在分布式应用系统中传递数据
......
一、对象序列化的概念
我们的程序运行在内存空间中,因此程序一关闭,这些对象也都会被CLR的垃圾回收机制销毁。程序第二次程序时,又重头来过。
如果希望第二次运行程序时能“重现"第一次运行时的“场景”,即恢复第一次运行时各个对象的状态,应用程序就必须采用某种
方法将对象各个字段的值保存到磁盘文件中,这样在需要时可以从磁盘文件中重新设置对象的各个字段值。
将一个内存中的对象保存到流中,并在需要时可以从流中重新读取数据重建对象的过程称为“对象的序列化Serialization” 与 “反序列化Deserialization”
二:流
用于保存对象序列化的存储介质是 流Stream
流是一个抽象的概念,它代表的是一连串有顺序的二进制数据。
比如一个打开的文件就可以看成是一个流。
在.net中,流被抽象为一个Stream类,此类在内部维护了一个读写指针,此指针所指向的位置就是流数据的读取点。Stream类提供了一个Seek方法来移动这个指针。
Stream 类定义了Read/ReadByte 和 Write/WriteByte 方法,以字节为基本单位存取数据。
Stream类是一个抽象类,在实际开发中多使用其子类(NetworkStream,FileStream,PipeStream,MemoryStream)。
这里面用得最多的就是两个类:代表一块内存区域的MemoryStream 和 代表文件的FileStream。下面选出FileStream类来讨论一下:
在.NET中,访问文件是通过FileStream对象进行的。
当应用程序需要访问文件时,必须先建立一个FileStream对象,此对象与文件是一一对应关系。
存取文件内容就相当于调用FileStream对象的相关方法,以下是读取一个文件内容的典型代码。
using(FileStream reader = new FileStream(FileName , FileMode.Open))
{
//调用Stream类所定义的Read()/ReadByte()系列方法从文件中读取数据....
}
由于Stream类所定义的read/readByte 和 Write/WriteByte 方法以字节为单位,在实际开发中用起来相当 不方便,比如如果需要将
一个double类型的数据写入到文件中,不得不调用writeByte 方法8次以写入8个字节(因为一个doulbe类型的数据占8个字节)。
为了方便向流中存取各种常见类型,.net基类库提供了以下两组辅助类:
1.BinaryReader 和 BinaryWrite :用于向流中读取和写入各种基本数据类型的数据
2.StreamReader 和 StreamWriter :用于从流中读取和写入字符串数据。
这两组4个类在实际开发中用得多。它们在底层都需要利用stream对象来完成真正的数据存取工作。
例如以下代码使用 StreamWrite对象向 hello.txt 文件中写入一个字符串:
using(FileStream fs = new FileStream("hello.txt" , FileMode.Create))
{
StreamWriter writer = new StreamWriter(fs);
writer.WriteLin("Hello!");
writer.Close();
}
之所以要介绍流,是因为对象序列后的数据就保存在流中。