1.什么是序列化
序列化是將對象狀態轉換為可保持或傳輸的格式的過程,在序列化過程中,對象的公共字段和私有字段以及類的名稱(包括包含該類的程序集)都被轉換為字節流,然后寫入數據流。與序列化相對的是反序列化,它將流轉換為對象。這兩個過程結合起來,可以輕松地存儲和傳輸數據。
2.為什么使用序列化
一個原因是將對象的狀態保持在存儲媒體中,以便可以在以后重新創建精確的副本。
我們經常需要將對象的字段值保存到磁盤中,並在以后檢索此數據。盡管不使用序列化也能完成這項工作,但這種方法通常很繁瑣而且容易出錯,並且在需要跟蹤對象的層次結構時,會變得越來越復雜。可以想象一下編寫包含大量對象的大型業務應用程序的情形,程序員不得不為每一個對象編寫代碼,以便將字段和屬性保存至磁盤以及從磁盤還原這些字段和屬性。序列化提供了輕松實現這個目標的快捷方法。
另一個原因是通過值將對象從一個應用程序域發送到另一個應用程序域中。
例如,序列化可用於在 ASP.NET 中保存會話狀態並將對象復制到 Windows 窗體的剪貼板中。遠程處理還可以使用序列化通過值將對象從一個應用程序域傳遞到另一個應用程序域中。
公共語言運行時 (CLR) 管理對象在內存中的分布,.NET 框架則通過使用反射提供自動的序列化機制。對象序列化后,類的名稱、程序集以及類實例的所有數據成員均被寫入存儲媒體中。對象通常用成員變量來存儲對其他實例的引用。類序列化后,序列化引擎將跟蹤所有已序列化的引用對象,以確保同一對象不被序列化多次。.NET 框架所提供的序列化體系結構可以自動正確處理對象圖表和循環引用。對對象圖表的唯一要求是,由正在進行序列化的對象所引用的所有對象都必須標記為 Serializable(請參閱基本序列化)。否則,當序列化程序試圖序列化未標記的對象時將會出現異常。
當反序列化已序列化的類時,將重新創建該類,並自動還原所有數據成員的值。
(序列化技術的主要兩個目的是:持久化存儲、按值封送。)
3.如何實現對象的序列化及反序列化
要實現對象的序列化,首先要保證該對象可以序列化。而且,序列化只是將對象的屬性進行有效的保存,對於對象的一些方法則無法實現序列化的。
實現一個類可序列化的最簡便的方法就是增加Serializable屬性標記類。
即可實現該類的可序列化。注意序列化的類必須為Public,否則不能夠被序列化。
要將該類的實例序列化為到文件中 .NET FrameWork提供了三種方法:
XML序列化
添加System.Runtime.Serialization.Formatters.Binary命名空間;
二進制序列化
添加System.Xml.Serialization命名空間;
NoSerialized屬性被Xmllgnore屬性替代;
soap序列化
典型應用:web service.
4.實現自定義序列化
如果你對數據流的組織方式不完全滿意,那么可以通過在自定義類中實現接口ISerializable來自定義序列化,這個接口只有一個方法:GetObjectData,這個方法用於將對類對象進行序列化所需要的數據填進SerializationInfo對象。
另外還需提供一個格式化構造器,這個構造器的參數列表與GetObjectData相同,並且要聲明為私有的。這個格式化器的作用是構造SerializationInfo對象,然后在序列化時調用GetObjectData。
示例如下:
using System; using System.Data; using System.Configuration; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters.Binary; /**//// ﹤summary﹥ /// Employee 的摘要說明 /// ﹤/summary﹥ [Serializable] public class Employee:ISerializable { public int EmpId=100; public string EmpName="劉德華"; [NonSerialized] public string NoSerialString = "NoSerialString-Test"; public Employee() { // // TODO: 在此處添加構造函數邏輯 // } private Employee(SerializationInfo info, StreamingContext ctxt) { EmpId = (int)info.GetValue("EmployeeId", typeof(int)); EmpName = (String)info.GetValue("EmployeeName",typeof(string)); //NoSerialString = (String)info.GetValue("EmployeeString",typeof(string)); } public void GetObjectData(SerializationInfo info, StreamingContext ctxt) { info.AddValue("EmployeeId", EmpId); info.AddValue("EmployeeName", EmpName); //info.AddValue("EmployeeString", NoSerialString); } }
C#序列化和反序列化方法:
public void OtherEmployeeClassTest() { Employee mp = new Employee(); mp.EmpId = 10; mp.EmpName = "邱楓"; mp.NoSerialString = "你好呀"; Stream steam = File.Open("c:\\temp3.dat", FileMode.Create); BinaryFormatter bf = new BinaryFormatter(); Response.Write("Writing Employee Info:"); bf.Serialize(steam,mp); steam.Close(); mp = null; //C#序列化和反序列化之反序列化 Stream steam2 = File.Open("c:\\temp3.dat", FileMode.Open); BinaryFormatter bf2 = new BinaryFormatter(); Response.Write("Reading Employee Info:"); Employee mp2 = (Employee)bf2.Deserialize(steam2); steam2.Close(); Response.Write(mp2.EmpId); Response.Write(mp2.EmpName); Response.Write(mp2.NoSerialString); }
原文地址:http://skybirdzw.blog.163.com/blog/static/7257062620125371316992/