1. 程式人生 > >C#中的序列化和反序列化是什麼、有什麼作用、使用方法詳解

C#中的序列化和反序列化是什麼、有什麼作用、使用方法詳解

什麼是序列化與反序列化???

序列化和反序列化,我們可能經常會聽到,其實通俗一點的解釋,序列化就是把一個物件儲存到一個檔案或資料庫欄位中去,反序列化就是在適當的時候把這個檔案再轉化成原來的物件使用。

 當兩個程序在進行遠端通訊時,彼此可以傳送各種型別的資料。無論是何種型別的資料,都會以二進位制序列的形式在網路上傳送。傳送方需要把這個物件轉換為位元組序列,才能在網路上傳送;接收方則需要把位元組序列再恢復為物件。
  把物件轉換為位元組序列的過程稱為物件的序列化。
  把位元組序列恢復為物件的過程稱為物件的反序列化。

物件的序列化主要有兩種用途:
  1) 把物件的位元組序列永久地儲存到硬碟上,通常存放在一個檔案中;
  我們經常需要將物件的欄位值儲存到磁碟中,並在以後檢索此資料。儘管不使用序列化也能完成這項工作,但這種方法通常很繁瑣而且容易出錯,並且在需要跟蹤物件的層次結構時,會變得越來越複雜。可以想象一下編寫包含大量物件的大型業務應用程式的情形,程式設計師不得不為每一個物件編寫程式碼,以便將欄位和屬性儲存至磁碟以及從磁 盤還原這些欄位和屬性。序列化提供了輕鬆實現這個目標的快捷方法。公共語言執行時 (CLR) 管理物件在記憶體中的分佈,.NET 框架則通過使用反射提供自動的序列化機制。物件序列化後,類的名稱、程式集以及類例項的所有資料成員均被寫入儲存媒體中。物件通常用成員變數來儲存對其他例項的引用。類序列化後,序列化引擎將跟蹤所有已序列化的引用物件,以確保同一物件不被序列化多次。.NET 框架所提供的序列化體系結構可以自動正確處理物件圖表和迴圈引用。對物件圖表的唯一要求是,由正在進行序列化的物件所引用的所有物件都必須標記為 Serializable(請參閱基 本序列化)。否則,當序列化程式試圖序列化未標記的物件時將會出現異常。當反序列化已序列化的類時,將重新建立該類,並自動還原所有資料成員的值。

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

序列化和反序列化的主要作用有:

  1、在程序下次啟動時讀取上次儲存的物件的資訊

  2、在不同的AppDomain或程序之間傳遞資料

  3、在分散式應用系統中傳遞資料

  .............

常見的序列化的方法:

  1、BinaryFormatter

  2、SoapFormatter

  3、XML序列化

用法:

  BinaryFormatter的用法大致如下:  

//BinaryFormatter將物件序列化到檔案中
List<string> inputList = new List<string>() { "潮流時尚公子","http://gz168168.taobao.com","歡迎專注技術的程式袁來看看筆者的網店哦"};
using (FileStream fsWriter = new FileStream(@"gz168168.tmp",FileMode.Create,FileAccess.Write))
{
       BinaryFormatter bf = new BinaryFormatter();
       //序列化
       bf.Serialize(fsWriter, inputList);
}

//BinaryFormatter將檔案中的資料反序列化出來
List<string> outputList = new List<string>();
using (FileStream fsReader = new FileStream(@"gz168168.tmp",FileMode.Open,FileAccess.Read))
{
       BinaryFormatter bf = new BinaryFormatter();
       //反序列化
       outputList = (List<string>)bf.Deserialize(fsReader);
}

  XML序列化的用法大致如下: 

//xml序列化到test.xml檔案中
List<string> inputList = new List<string>() { "潮流時尚公子","http://gz168168.taobao.com"};
using (FileStream fsWriter = new FileStream(@"test.xml",FileMode.Create,FileAccess.Write))
{
      XmlSerializer xs = new XmlSerializer(typeof(List<string>));
      xs.Serialize(fsWriter, inputList);
}

//從test.xml檔案中反序列化出來
List<string> outputList = new List<string>();
using (FileStream fsReader = new FileStream(@"test.xml",FileMode.Open,FileAccess.Read))
{
     XmlSerializer xs = new XmlSerializer(typeof(List<string>));
     outputList = xs.Deserialize(fsReader) as List<string>;
}

總結:

兩個的用法大致如下:

序列化:

  1.得到一個儲存物件的型別

  2.建立一個寫入檔案流

  3.定義要序列化的型別

  4.呼叫序列化方法

反序列化:

  1.定義一個裝載物件的型別

  2.建立一個讀出檔案流

  3.定義要反序列化的型別

  4.呼叫反序列化方法

BinaryFormatter類進行序列化和反序列化,以縮略型二進位制格式寫到一個檔案中去,速度比較快,而且寫入後的檔案已二進位制儲存有一定的保密效果。標記為NonSerialized的其他所有成員都能序列化。

採用xml序列化的方式只能儲存public的欄位和可讀寫的屬性,對於private等型別的欄位不能進行序列化。

二進位制序列化的優點: 

  1. 所有的類成員(包括只讀的)都可以被序列化;

  2. 效能非常好。

XML序列化的優點:

  1. 互操作性好;

  2. 不需要嚴格的二進位制依賴;

  3. 可讀性強

SoapFormatter微軟淘汰了,,不能序列化泛型,這裡就不多講了。