轉載自:http://www.cnblogs.com/Tim_Liu/archive/2010/11/09/1872587.htmlhtml
序列化是指一個對象的實例能夠被保存,保存成一個二進制串,固然,一旦被保存成二進制串,那麼也能夠保存成文本串了。
好比,一個計數器,數值爲2,咱們能夠用字符串「2」表示。
若是有個對象,叫作connter,當前值爲2,那麼能夠序列化成「2」,反向的,也能夠從「2」獲得值爲2的計數器實例。
這樣,關機時序列化它,開機時反序列化它,每次開機都是延續的。不會都是從頭開始。web
序列化概念的提出和實現,可使咱們的應用程序的設置信息保存和讀取更加方便。編程
序列化有不少好處,好比,在一臺機器上產生一個實例,初始化完畢,而後能夠序列化,經過網絡傳送到另外一臺機器,而後反序列化,獲得對象實例,以後再執行某些業務邏輯,獲得結果,再序列化,返回第一臺機器,第一臺機器獲得對象實例,獲得結果。
這個例子是目前比較先進的「智能代理」的原理。api
當前比較熱火的web services使用soap協議,soap協議也是以對象的可序列化爲基礎的。數組
「序列化」可被定義爲將對象的狀態存儲到存儲媒介中的過程。在此過程當中,對象的公共字段和私有字段以及類的名稱(包括包含該類的程序集)都被轉換爲字節流,而後寫入數據流。在之後「反序列化」該對象時,建立原始對象的精確複本。
1、爲何要選擇序列化
一個緣由是將對象的狀態保持在存儲媒體中,以即可以在之後從新建立精確的副本;
另外一個緣由是經過值將對象從一個應用程序域發送到另外一個應用程序域中。
例如,序列化可用於在 ASP.NET 中保存會話狀態並將對象複製到 Windows 窗體的剪貼板中。遠程處理還可使用序列化經過值將對象從一個應用程序域傳遞到另外一個應用程序域中。
2、如何實現對象的序列化及反序列化
要實現對象的序列化,首先要保證該對象能夠序列化。並且,序列化只是將對象的屬性進行有效的保存,對於對象的一些方法則沒法實現序列化的。
實現一個類可序列化的最簡便的方法就是增長Serializable屬性標記類。如:
[Serializable()]
public class MEABlock
{
private int m_ID;
public string Caption;緩存
public MEABlock()
{
///構造函數
}
}
便可實現該類的可序列化。
要將該類的實例序列化爲到文件中?.NET FrameWork提供了兩種方法:
一、XML序列化
使用 XmLSerializer 類,可將下列項序列化。 安全
要實現上述類的實例的序列化,可參照以下例子:
MEABlock myBlock = new MEABlock();
// Insert code to set properties and fields of the object.
XmlSerializer mySerializer = new XmlSerializer(typeof(MEABlock));
// To write to a file, create a StreamWriter object.
StreamWriter myWriter = new StreamWriter("myFileName.xml");
mySerializer.Serialize(myWriter, MEABlock);
須要注意的是XML序列化只會將public的字段保存,對於私有字段不予於保存。
生成的XML文件格式以下:
<MEABlock>
<Caption>Test</Caption>
</MEABlock>
對於對象的反序列化,則以下:
MEABlock myBlock;
// Constructs an instance of the XmlSerializer with the type
// of object that is being deserialized.
XmlSerializer mySerializer = new XmlSerializer(typeof(MEABlock));
// To read the file, creates a FileStream.
FileStream myFileStream = new FileStream("myFileName.xml", FileMode.Open);
// Calls the Deserialize method and casts to the object type.
myBlock = (MEABlock)mySerializer.Deserialize(myFileStream)
二、二進制序列化
與XML序列化不一樣的是,二進制序列化能夠將類的實例中全部字段(包括私有和公有)都進行序列化操做。這就更方便、更準確的還原了對象的副本。
要實現上述類的實例的序列化,可參照以下例子:
MEABlock myBlock = new MEABlock();
// Insert code to set properties and fields of the object.
IFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream("MyFile.bin",FileMode.Create,FileAccess.Write, FileShare.None);
formatter.Serialize(stream, myBlock);
stream.Close();
對於對象的反序列化,則以下:
IFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream("MyFile.bin", FileMode.Open,FileAccess.Read, FileShare.Read);
MEABlock myBlock = (MEABlock) formatter.Deserialize(stream);
stream.Close();
3、如何變相實現自定義可視化控件的序列化、反序列化
對於WinForm中自定義控件,因爲繼承於System.Windows.Form類,而Form類又是從MarshalByRefObject繼承的,窗體自己沒法作到序列化,窗體的實現基於Win32下GUI資源,不能脫離當前上下文存在。
固然能夠採用變通的方法實現控件的序列化。這裏採用的是記憶類模型。
定義記憶類(其實就是一個可序列化的實體類)用於記錄控件的有效屬性,須要序列化控件的時候,只須要將該控件的實例Copy到記憶類,演變成序列化保存該記憶類的操做。
反序列化是一個逆過程。將數據流反序列化成爲該記憶類,再根據該記憶類的屬性生成控件實例。而對於控件的一些事件、方法則能夠繼續使用。服務器
XML 序列化僅將對象的公共字段和屬性值序列化爲 XML 流。XML 序列化不包括類型信息。例如,若是您有一個存在於 Library 命名空間中的 Book 對象,將不能保證它將會被反序列化爲同一類型的對象。網絡
注意 XML 序列化不轉換方法、索引器、私有字段或只讀屬性(只讀集合除外)。若要序列化對象的全部字段和屬性(公共的和私有的),請使用 BinaryFormatter,而不要使用 XML 序列化。
XML 序列化中最主要的類是 XmlSerializer 類,它的最重要的方法是 Serialize 和 Deserialize 方法。XmlSerializer 生成的 XML 流符合萬維網聯合會 (www.w3.org) XML 架構定義語言 (XSD) 1.0 的建議。另外,生成的數據類型符合標題爲「XML Schema Part 2: Datatypes」(XML 架構第二部分:數據類型)的文檔。架構
對象中的數據是用編程語言構造(如類、字段、屬性、基元類型、數組,甚至 XmlElement 或 XmlAttribute 對象形式的嵌入 XML)來描述的。您能夠建立本身的用屬性批註的類,或者使用 XML 架構定義工具生成基於現有 XML 架構的類。
若是您有 XML 架構,就可運行 XML 架構定義工具生成一組強類型化爲架構並用屬性批註的類。當序列化這樣的類的實例時,生成的 XML 符合 XML 架構。使用這樣的類,就可針對容易操做的對象模型進行編程,同時確保生成的 XML 符合 XML 架構。這是使用 .NET Framework 中的其餘類(如 XmlReader 和 XmlWriter 類)分析和寫 XML 流的一種替換方法。(有關使用這些類的更多信息,請參見使用 .NET Framework 中的 XML。)這些類使您能夠分析任何 XML 流。與此相反,當須要 XML 流符合已知的 XML 架構時,請使用 XmlSerializer。
屬性控制由 XmlSerializer 類生成的 XML 流,使您能夠設置 XML 流的 XML 命名空間、元素名、屬性名等。有關這些屬性和它們如何控制 XML 序列化的更多信息,請參見使用屬性控制 XML 序列化。若想得到一個列示對所生成的 XML 起控制做用的那些屬性的表,請參見控制 XML 序列化的屬性。
XmlSerializer 類可進一步序列化對象並生成編碼的 SOAP XML 流。生成的 XML 符合標題爲「Simple Object Access Protocol (SOAP) 1.1」的萬維網聯合會文檔的第 5 節。有關此過程的更多信息,請參見用 XML 序列化生成 SOAP 消息。有關控制生成的 XML 的屬性表,請參見控制編碼的 SOAP 序列化的屬性。
XmlSerializer 類生成由 XML Web services 建立和傳遞給 XML Web services 的 SOAP 消息。若要控制 SOAP 消息,可將屬性應用於 XML Web services 文件 (.asmx) 中的類、返回值、參數和字段。您能夠同時使用在「控制 XML 序列化的屬性」中列出的屬性和在「控制編碼的 SOAP 序列化的屬性」中列出的屬性,由於 XML Web services 可使用文本樣式,也可使用編碼的 SOAP 樣式。有關使用屬性控制 XML Web services 所生成的 XML 的更多信息,請參見 XML Web services 的 XML 序列化。有關 SOAP 和 XML Web services 的更多信息,請參見自定義 SOAP 消息。
在建立使用 XmlSerializer 的應用程序時,您應當瞭解如下幾點以及它們的影響:
代碼和 DLL 在建立和進行編譯時,易於遭受惡意進程的攻擊。若是所使用的計算機運行的是 Microsoft Windows NT 4.0 或更高版本,則有可能會有兩個或更多用戶共享臨時目錄。若是同時存在如下兩種狀況,則共享臨時目錄是有危險性的:(1) 兩個賬戶有不一樣的安全特權;(2) 具備較高特權的賬戶運行一個使用 XmlSerializer 的應用程序。在這種狀況下,某一用戶能夠替換所編譯的 .cs 或 .dll 文件,由此破壞計算機的安全性。爲了不發生這一問題,請始終確保計算機上的每一賬戶都有本身的配置文件。若是可以保證這一點的話,默認狀況下,TEMP 環境變量就會爲不一樣的賬戶指定不一樣的目錄。
若是您所使用的計算機運行 Internet 信息服務 (IIS),而且您的應用程序是在 IIS 下運行,就能夠避免這類攻擊。IIS 帶有一個控制門,用於禁止處理大於設定數量(默認值是 4 KB)的數據流。若是您所建立的應用程序不使用 IIS,同時該應用程序使用 XmlSerializer 進行反序列化,則應該實現一個相似的控制門,以阻止拒絕服務攻擊。
惡意對象施加威脅的方式有兩種。一種是運行惡意代碼,另外一種是將惡意代碼插入到由 XmlSerializer 建立的 C# 文件中。在第一種狀況下,若是惡意對象試圖運行破壞性過程,代碼訪問安全性將幫助防止發生任何破壞。在第二種狀況下,在理論上,惡意對象有可能會以某種方式將代碼插入到由 XmlSerializer 建立的 C# 文件中。儘管對這一問題已進行了完全的檢驗,並且這類攻擊被認爲是不可能的,但您仍是應該當心一些,必定不要序列化那些不可信的未知類型的數據。
XmlSerializer 對數據進行了序列化以後,數據能夠被存儲爲 XML 文件,或存儲在其餘數據存儲區。若是其餘進程能夠訪問到您的數據存儲區,或是能夠在 Intranet 或 Internet 上看到該數據存儲區,數據就可能被竊取,並被惡意使用。例如,若是您建立了一個應用程序,對包含信用卡號碼的訂單進行序列化,這一數據就很是重要。爲了防 止發生這一問題,請始終保護您的數據存儲區,並對數據採起保密措施。
下面的示例顯示一個具備公共字段的簡單類:
[Visual Basic]Public Class OrderForm Public OrderDate As DateTimeEnd Class[C#]public class OrderForm{ public DateTime OrderDate;}
當將此類的實例序列化時,該實例可能相似於下面的代碼:
<OrderForm> <OrderDate>12/12/01</OrderDate></OrderForm>
有關序列化的更多示例,請參見 XML 序列化的示例。
使用 XmLSerializer 類,可將下列項序列化。
若要序列化對象,首先建立要序列化的對象並設置它的公共屬性和字段。爲此,必須肯定要用以存儲 XML 流的傳輸格式(或者做爲流,或者做爲文件)。例如,若是 XML 流必須以永久形式保存,則建立 FileStream 對象。當您反序列化對象時,傳輸格式肯定您將建立流仍是文件對象。肯定了傳輸格式以後,就能夠根據須要調用 Serialize 或 Deserialize 方法。
序列化對象
[Visual Basic]Dim myObject As MySerializableClass = New MySerializableClass()' Insert code to set properties and fields of the object.Dim mySerializer As XmlSerializer = New XmlSerializer(GetType(MySerializableClass))' To write to a file, create a StreamWriter object.Dim myWriter As StreamWriter = New StreamWriter("myFileName.xml")mySerializer.Serialize(myWriter, myObject)[C#]MySerializableClass myObject = new MySerializableClass();// Insert code to set properties and fields of the object.XmlSerializer mySerializer = new XmlSerializer(typeof(MySerializableClass));// To write to a file, create a StreamWriter object.StreamWriter myWriter = new StreamWriter("myFileName.xml");mySerializer.Serialize(myWriter, myObject);
反序列化對象
[Visual Basic]Dim myObject As MySerializableClass' Constructs an instance of the XmlSerializer with the type' of object that is being deserialized.Dim mySerializer As XmlSerializer = New XmlSerializer(GetType(MySerializableClass))' To read the file, creates a FileStream.Dim myFileStream As FileStream = _New FileStream("myFileName.xml", FileMode.Open)' Calls the Deserialize method and casts to the object type.myObject = CType( _mySerializer.Deserialize(myFileStream), MySerializableClass)[C#]MySerializableClass myObject;// Constructs an instance of the XmlSerializer with the type// of object that is being deserialized.XmlSerializer mySerializer = new XmlSerializer(typeof(MySerializableClass));// To read the file, creates a FileStream.FileStream myFileStream = new FileStream("myFileName.xml", FileMode.Open);// Calls the Deserialize method and casts to the object type.myObject = (MySerializableClass) mySerializer.Deserialize(myFileStream)
有關 XML 序列化的更多示例,請參見 XML 序列化的示例。
XmlSerializer 類在您將對象序列化爲 XML 時爲您提供完整而靈活的控制。若是您正在建立 XML Web services,則能夠將控制序列化的屬性應用於類和成員以確保 XML 輸出符合特定的架構。
例如,XmlSerializer 使您可以:
XML 序列化的另外一個好處是:只要生成的 XML 流符合給定的架構,則對於所開發的應用程序就沒有約束。假定有這樣一個用於描述圖書的架構,它具備標題、做者、出版商和 ISBN 編號元素。您能夠開發一個以您但願的任何方式(例如,做爲圖書訂單,或做爲圖書清單)處理 XML 數據的應用程序。在任一種狀況下,惟一的要求是 XML 流應當符合指定的 XML 架構定義語言 (XSD) 架構。
使用 XmlSerializer 類時,應考慮下列狀況:
標題爲「XML Schema Part 2: Datatypes」的萬維網聯合會 (www.W3.org) 文檔指定在 XML 架構定義語言 (XSD) 架構中容許使用的簡單數據類型。對於這些數據類型中的許多類型(例如,int 和 decimal),在 .NET Framework 中都有對應的數據類型。可是,某些 XML 數據類型在 .NET Framework 中沒有對應的數據類型(例如,NMTOKEN 數據類型)。在這樣的狀況下,若是使用 XML 架構定義工具 (Xsd.exe) 從架構生成類,就會將適當的特性應用於字符串類型的成員,並會將其 DataType 屬性設置爲 XML 數據類型名稱。例如,若是架構包含一個數據類型爲 XML 數據類型 NMTOKEN 的、名爲「MyToken」的元素,則生成的類可能包含如下示例中的成員。
[Visual Basic]<XmlElement(DataType:="NMTOKEN")>Public MyToken As String[C#][XmlElement(DataType = "NMTOKEN")]public string MyToken;
與此相似,若是建立一個必須符合特定 XML 架構 (XSD) 的類,應當應用適當的特性並將它的 DataType 屬性設置爲所需的 XML 數據類型名稱。
有關類型映射的完整列表,請參見下列任意一個特性類的 DataType 屬性:SoapAttributeAttribute、SoapElementAttribute、XmlArrayItemAttribute、XmlAttributeAttribute、XmlElementAttribute 或 XmlRootAttribute。