1、什么是对象序列化?
术语:序列化(Serialization)描述了持久化(可能还需要传输数据)一个对象的状态到流(如文件流、内存流)的过程。
被持久化的数据次序包括所有以后需要重建(反序列化)对象状态所必须的信息。
使用这种技术的好处是用最小的花费来保存海量的数据。
比如说我们在对酷狗音乐进行界面设置的时候,如颜色,个人爱好等等设置,这些信息我们保存在哪里呢?害怕被别人看见?咋办?使用序列化我们可以把数据编程乱码,这样别人轻易看不见的,文件的后缀名可以自己来定义如A.bat、B.bin。。。。
那么反序列化就是将序列化的数据读取出来
2、对象序列化的形式
*二进制形式--BinaryFormatter--using System.Runtime.Serialization.Formatters.Binary;
*SOAP(简单对象访问协议)形式--using System.Runtime.Serialization.Formatters.Soap;--需添加引用
*XML形式--XmlSerializer-using System.Xml.Serialization;--需添加引用
BinaryFormatter类型使用紧凑的二进制格式将对象图序列化为一个流
SoapFormatter类型将对象图表示为一个SOAP消息(传递消息到Web服务或从Web服务传递消息的标准XML文件)
XmlSerializer类型将数据转化为XML格式,可以使用自己定义的XML架构或文档类型定义(DTD)
对象序列化的结果是将数据保存为自定义的格式保存在本地硬盘或者内存流中
当然不管选择哪种格式化程序来序列化对象,其最终是直接派生于System.Object,因此并不从一个以序列化为中心的基类共享一组公共的成员,但是其中的BinaryFormatter和SoapFormatter类型通过实现IFormatter和IRemotingFormatter接口都支持公共的成员,但XmlSerializer都不支持这两个接口成员
序列化集合:
其中BinaryFormatter和XmlSerializer都支持对集合的序列化,但是SoapFormatter却不支持
List<Student> students = new List<Student>(); 这时候序列化的对象是一个集合
3、配置序列化对象
首先说明的是不是所有的对象都能序列化,我们需要字为每一个关联的类或者结构添加 [Serializable]
,这里我们需要知道[Serializable]特性是不能被继承的,
因此如果从被标记为[Serializable]的类派生一个类,子类也必须被标记为[Serializable],否则它不能被持久化,当然我们也可以不让类中的某些属性方法被序列化,
可使用[NonSerialized] 特性来进行标记。
4、在格式化程序中的类型保真
在以上三种格式化程序中,最明显的不同是对象图被持久化为不同的流的方式。
所谓类型保证我理解的是不因外界环境的变化而似的被持久化过的数据(包括类型、版本等)也发生变化。
*使用BinaryFormatter序列化对象的时候跨越.NET应用程序机器边界传递对象时最为理想;
*使用SoapFormatter能通过使用XML命名空间来持久化原始程序集的跟踪;
*使用XML序列化可用于标准的.NET Web服务,可被任何平台的客户端调用;
说白了的话,要想保真就使用二进制序列化,但是他不能跨平台;如果想跨平台、框架的话SoapFormatter和XmlSerializer是不错的选择,但是缺点是类型不保真
代码如下:
class="code_img_closed" src="/Upload/Images/2013093023/0015B68B3C38AA5B.gif" alt="" />logs_code_hide('50a5cbf8-4d82-4da4-9c8a-f0357995244b',event)" src="/Upload/Images/2013093023/2B1B950FA3DF188F.gif" alt="" />class Program { static void Main( string[] args ) { Student stu = new Student(); stu.Name = "张三"; stu.Age = 12; stu.Sex = "男"; //BinaryFormatter以二进制格式持久化状态数据 #region 二进制序列化 //BinaryFormatter binFormat = new BinaryFormatter(); //using (Stream stream = new FileStream( "Student.dat", FileMode.Create, FileAccess.Write, FileShare.None )) //{ // binFormat.Serialize( stream, stu ); //} //Console.WriteLine( "二进制序列化完成" ); //Console.ReadKey(); #endregion #region 二进制反序列化 BinaryFormatter binDeFormat = new BinaryFormatter(); using (Stream stream = File.OpenRead( "NewStudent.dat" )) { Student student = binDeFormat.Deserialize( stream ) as Student; Console.WriteLine(student.Name+" "+student.Age.ToString()+" "+student.Sex); student.Tell(); Console.ReadKey(); } #endregion //SoapFormatter以简单对象访问协议来持久化状态数据 #region Soap序列化 //SoapFormatter soapFormat = new SoapFormatter(); //using (Stream stream = new FileStream( "Student.soap", FileMode.Create, FileAccess.Write, FileShare.None )) //{ // soapFormat.Serialize( stream, stu ); // Console.WriteLine( "Soap序列化完成" ); //} //Console.ReadLine(); #endregion #region Soap反序列化 //SoapFormatter soapDeFormat = new SoapFormatter(); //using (Stream stream = File.OpenRead( "Student.soap" )) //{ // Student student = soapDeFormat.Deserialize( stream ) as Student; // stu.Tell(); // Console.WriteLine( "Soap反序列化完成" ); //} //Console.ReadKey(); #endregion //XML以可扩展标记语言来持久化状态数据 #region XML序列化 //XmlSerializer xmlFormat = new XmlSerializer( typeof( Student ) ); //using (Stream stream = new FileStream( "Student.xml", FileMode.Create, FileAccess.Write, FileShare.None )) //{ // xmlFormat.Serialize( stream, stu ); // Console.WriteLine( "XML序列化完成" ); //} //Console.ReadKey(); #endregion #region XML反序列化 //XmlSerializer xmlDeFormat = new XmlSerializer( typeof( Student ) ); //using (Stream stream = File.OpenRead( "Student.xml" )) //{ // Student student = xmlDeFormat.Deserialize( stream ) as Student; // student.Tell(); // Console.WriteLine( "XML反序列化完成" ); //} //Console.ReadKey(); #endregion List<Student> students = new List<Student>(); students.Add( new Student( "张三", 12, "男" ) ); students.Add( new Student( "李四", 13, "男" ) ); students.Add( new Student( "赵六", 14, "男" ) ); #region 二进制序列化集合 //BinaryFormatter binFormat = new BinaryFormatter(); //using (Stream stream = new FileStream( "Students.bat", FileMode.Create, FileAccess.Write, FileShare.None )) //{ // binFormat.Serialize( stream, students ); // Console.WriteLine( "Binary序列化集合完成" ); //} //Console.ReadKey(); #endregion #region 二进制反序列化集合 //BinaryFormatter binDeFormat = new BinaryFormatter(); //using (Stream stream = File.OpenRead( "Students.bat" )) //{ // List<Student> stuS=binDeFormat.Deserialize(stream) as List<Student>; // foreach (var item in stuS) // { // item.Tell(); // } // Console.WriteLine("二进制集合反序列化完成"); //} //Console.ReadKey(); #endregion #region Soap序列化集合--不支持 //SoapFormatter soapFormat = new SoapFormatter(); //using (Stream stream = new FileStream( "Studnets.soap", FileMode.Create, FileAccess.Write, FileShare.None )) //{ // soapFormat.Serialize( stream, students ); // Console.WriteLine( "Soap序列化集合完成" ); //} //Console.ReadKey(); #endregion #region Soap反序列化集合--不支持 //SoapFormatter soapDeFormat = new SoapFormatter(); //using (Stream stream = File.OpenRead( "Studnets.soap" )) //{ // List<Student> stuS = soapDeFormat.Deserialize( stream ) as List<Student>; // foreach (var item in stuS) // { // Console.WriteLine( item.Name ); // } //} //Console.ReadKey(); #endregion #region XML序列化集合 //XmlSerializer xmlFormat = new XmlSerializer( typeof( List<Student> ) ); //using(Stream stream=new FileStream("Students.xml",FileMode.Create,FileAccess.Write,FileShare.None)) //{ // xmlFormat.Serialize( stream, students ); // Console.WriteLine("XML序列化集合完成"); //} //Console.ReadKey(); #endregion #region XML反序列化集合 //XmlSerializer xmlDeFormat = new XmlSerializer(typeof(List<Student>)); //using (Stream stream = File.OpenRead( "Students.xml" )) //{ // List<Student> stuS = xmlDeFormat.Deserialize( stream ) as List<Student>; // foreach (var student in stuS) // { // Console.WriteLine(student.Name); // } //} //Console.ReadKey(); #endregion }View Code
使用特性来实现自定义序列化
[Serializable] class Student { private string _name; private string _sex; public string Name { get { return _name; } set { this._name = value; } } public string Sex { get { return _sex; } set { this._sex = value; } } [OnSerializing] private void OnSerializing(StreamingContext context) { _name = _name.ToUpper(); _sex = _sex.ToUpper(); } [OnSerialized] private void OnSerizlizing(StreamingContext context) { _name = _name.ToUpper(); _sex = _sex.ToUpper(); } }View Code
以上学习总结如有不当之处烦请指教