也說序列化

來源:互聯網
上載者:User
  概述:

序列化(serialization)是指將一個對象的目前狀態轉換成位元組流(a stream of bytes)的過程,而反序列化(deserialization)則指序列化過程的逆過程,將位元組流轉換成一個對象。初聽起來可能對此不太感興趣,但是使用序列化卻有許多重要的原因。一旦將某一對象序列化,得到的位元組可以儲存在檔案、資料庫,或記憶體中——只要是可以儲存的任何地方。需要恢複對象時,僅僅只需從它儲存的位置反序列化即可。對象固有的這種特性對於無狀態的Web應用程式是非常重要的,因為它允許重要的狀態資訊可以在使用者請求之間保留。

序列化也允許對象在應用程式邊界之間傳遞,編程人員可以將描述對象狀態的位元組流在網路上傳遞,並在另一端反序列化成一個匹配的對象。從本質上講,序列化允許對象以“數值”的方式傳遞給另一個應用程式。.NET遠程架構廣泛地在進程之間使用序列化來編組對象資料。

序列化不是.NET新引入的概念,Windows程式員同各種各樣的序列化打交道:MFC中的歸檔機制、Visuabl Basic的PropertyBag和COM的IPersistStream介面等,都具有類似的特性。那麼.NET序列化與這些方式又有什麼區別呢?一個字,簡單。在.NET以前的開發環境中,序列化是一個手工定製,對於類設計人員來說,實作類別的序列化並不困難,但是實現難度較大的設計,它就顯得能麻煩、耗時。在.NET中,該過程完全是自動進行的,使用者所做的就是使用Serializable特性來標記一個能序列化的類,運行庫做餘下的事。

.NET運行庫怎樣實現這一捷徑的呢?當然是利用鏡像,或更為準確地說是反射。前面提到,程式集含有名為中繼資料的自描述(self-describing)資料,程式集的中繼資料完整地表述了內部每一個類型,包括類型中每個私人欄位的資訊。通過反射過程,運行庫能識別中繼資料,並用它來決定類應怎樣被序列化。

使用Serializable特性實現序列化:
前面已經提到,如果允許運行庫序列化一個對象,必須將該類標記上Serializable特性。下面的代碼定義了兩個標記了Serialable特性的類。

[Serializable]

public class Car

{

private string mColor;

private int mTopSpeed;

//Reference to another object

private Radio mRadio;

[NonSerialized] //Runtime will not serialize this field

private string mNickName;

public Car(string nickName, int topSpeed, string color)

{

mNickName = nickName;

mTopSpeed = topSpeed;

mColor = color;

mRadio = new Radio();

}

}

[Serializable]

public class Radio

{

private int mVolume = 5;

}

如上所示,Car類的mNickName欄位用NonSerialized特性標註,指示運行庫進行序列化時跳過該項,而其他部分允許進行序列化。這裡注意,mRadio是對另一對象的引用,意味著運行庫必須對其序列化。事實上,當運行庫被告知要對某個對象序列化時,使用給定的對象作為根,建立一個對象圖表(類似於記憶體回收行程)。所有在圖表中的對象也必須可被序列化的,否則運行庫將引發異常。

下面的代碼舉例說明如何將Car對象序列化到一個檔案之中。

static void Main(string[] args)

{

Car myCar = new Car("Christine", 150, "Red");

FileStream mySoapFile = File.Create("Car.txt");

// Use a SOAP formatter object to serialize the object.

new SoapFormatter().Serialize(mySoapFile, myCar);

mySoapFile.Close();

}

運行庫不控制序列化資料的實際格式,但是有一個專門進行格式化的對象負責對序列化輸出進行格式化。.NET架構有兩種格式化程式:SOAP格式化程式和二進位格式化程式。在前面的例子中,SoapFormatter對象將對象序列化進一個SOAP報文,並將其發送到特定的流中。圖2-26顯示了在執行完這段代碼後Car.txt中的內容。

如果仔細查看圖2-26,很容易發現SOAP是如何描繪每個對象和它的資料成員。這種方式通過增加檔案大小來提高了可讀性。二進位格式化程式使用了更為緊湊的格式。如果需要在網路間發送對象,這種方式就更重要,尤其是在需要考慮網路頻寬而不強調可讀性的情況下。

通過調用SoapFormatter.Dewerialize方法,就可將該對象讀入記憶體中:

static void Rehydrate()

{

FileStream mySoapFile = File.Open("Car.txt", FileMode.Open);

Car myCar = (Car) new SoapFormatter().Deserialize(mySoapFile);

mySoapFile.Close();

}

圖2-26  使用SOAP格式化程式對Car對象進行序列化

註:摘自《NET分布式編程——C#篇 》

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.