天天看點

.Net 中的序列化與反序列化 (轉)

< DOCTYPE html PUBLIC -WCDTD XHTML StrictEN httpwwwworgTRxhtmlDTDxhtml-strictdtd>

   一、概述

    當兩個程序在進行遠端通信時,彼此可以發送各種類型的資料。無論是何種類型的資料,都會以二進制序列的形式在網絡上傳送。發送方需要把這個對象轉換為位元組序列,才能在網絡上傳送;接收方則需要把位元組序列再恢複為對象。

    把對象轉換為位元組序列的過程稱為對象的序列化。

    把位元組序列恢複為對象的過程稱為對象的反序列化。

    二、對象的序列化主要有兩種用途:

   1) 把對象的位元組序列永久地儲存到硬碟上,通常存放在一個檔案中;

    我們經常需要将對象的字段值儲存到磁盤中,并在以後檢索此資料。盡管不使用序列化也能完成這項工作,但這種方法通常很繁瑣而且容易出錯,并且在需要跟蹤對象的層次結構時,會變得越來越複雜。可以想象一下編寫包含大量對象的大型業務應用程式的情形,程式員不得不為每一個對象編寫代碼,以便将字段和屬性儲存至磁盤以及從磁 盤還原這些字段和屬性。序列化提供了輕松實作這個目标的快捷方法。公共語言運作時 (CLR) 管理對象在記憶體中的分布,.NET 架構則通過使用反射提供自動的序列化機制。對象序列化後,類的名稱、程式集以及類執行個體的所有資料成員均被寫入存儲媒體中。對象通常用成員變量來存儲對其他執行個體的引用。類序列化後,序列化引擎将跟蹤所有已序列化的引用對象,以確定同一對象不被序列化多次。.NET 架構所提供的序列化體系結構可以自動正确處理對象圖表和循環引用。對對象圖表的唯一要求是,由正在進行序列化的對象所引用的所有對象都必須标記為 Serializable(請參閱基 本序列化)。否則,當序列化程式試圖序列化未标記的對象時将會出現異常。當反序列化已序列化的類時,将重新建立該類,并自動還原所有資料成員的值。

   2) 在網絡上傳送對象的位元組序列。

   對象僅在建立對象的應用程式域中有效。除非對象是從MarshalByRefObject派生得到或标記為 Serializable,否則,任何将對象作為參數傳遞或将其作為結果傳回的嘗試都将失敗。如果對象标記為 Serializable,則該對象将被自動序列化,并從一個應用程式域傳輸至另一個應用程式域,然後進行反序列化,進而在第二個應用程式域中産生出該對象的一個精确副本。此過程通常稱為按值封送。如果對象是從MarshalByRefObject派生得到,則從一個應用程式域傳遞至另一個應用程式域的是對象引用,而不是對象本身。也可以将從MarshalByRefObject派生得到的對象标記為Serializable。遠端使用此對象時,負責進行序列化并已預先配置為SurrogateSelector的格式化程式将控制序列化過程,并用一個代理替換所有從MarshalByRefObject派生得到的對象。如果沒有預先配置為SurrogateSelector,序列化體系結構将遵從下面的标準序列化規則.

     三、.NET提供了三種序列化方式

    [1]、XML Serializer

     [2]、SOAP Serializer

     [3]、BinarySerializer

    四、基本序列化

    要使一個類可序列化,最簡單的方法是使用 Serializable 屬性對它進行标記,如下所示:

    [Serializable]

    public class MyObject

    {

        public int n1 = 0;

        public int n2 = 0;

        public String str = null;

    }

   [BinarySerializer]

    将此類的一個執行個體序列化為一個檔案:

MyObject obj = new MyObject();

obj.n1 = 1;

obj.n2 = 24;

obj.str = "一些字元串";

IFormatter formatter = new BinaryFormatter();

Stream stream = new FileStream("MyFile.bin", FileMode.Create,

FileAccess.Write, FileShare.None);

formatter.Serialize(stream, obj);

stream.Close();

    反序列化:

Stream stream = new FileStream("MyFile.bin", FileMode.Open,

FileAccess.Read, FileShare.Read);

MyObject obj = (MyObject) formatter.Deserialize(fromStream);

  [XMLSerializer]

    将此類的執行個體序列化成一個Xml檔案.

XmlSerializer ser = new XmlSerializer(obj.GetType());

ser.Serialize(new FileStream(@"users.xml", FileMode.Create), obj);

    反序列化:

XmlSerializer serializer = new XmlSerializer(Type.GetType("MyObject"));

MyObject my=(MyObject)serializer.Deserialize(new FileStream(@"users.xml",FileMode.Open));

    說明:使用二進制格式化程式進行序列化。您隻需建立一個要使用的流和格式化程式的執行個體,然後調用格式化程式的 Serialize 方法。流和要序列化的對象執行個體作為參數提供給此調用。類中的所有成員變量(甚至标記為 private 的變量)都将被序列化,但這一點在本例中未明确展現出來。在這一點上,二進制序列化不同于隻序列化公共字段的 XML 序列化程式。将對象還原到它以前的狀态也非常容易。首先,建立格式化程式和流以進行讀取,然後讓格式化程式對對象進行反序列化。    

     [SOAP Serializer]

    如果要求具有可移植性,請使用 SoapFormatter。所要做的更改隻是将以上代碼中的BinaryFormatter換 SoapFormatter,而 Serialize 和 Deserialize 調用不變。

本文轉自 netcorner 部落格園部落格,原文連結: http://www.cnblogs.com/netcorner/archive/2009/01/09/2912093.html  ,如需轉載請自行聯系原作者