天天看點

如何将類序列化并直接存儲入資料庫一、二進制格式器 vs XML格式器 二、序列化機制對類的要求三、基本序列化、自定義序列化參考代碼1參考代碼2

   本文将從這兩個格式器入手,先向大家介紹分别用它們如何實作序列化和反序列化,然後比較兩種格式器的不同點。接着我會向大家介紹實作序列化對對象類型的一些要求,同時還要向大家介紹兩種不同的序列化方式:基本序列化(Basic Serialization)和自定義序列化(Custom Serialization)。最後,我還會給大家介紹一個執行個體程式以加深大家對序列化機制的了解程度。

  程式員在編寫應用程式的時候往往要将程式的某些資料存儲在記憶體中,然後将其寫入某個檔案或是将它傳輸到網絡中的另一台計算機上以實作通訊。這個将程式資料轉化成能被存儲并傳輸的格式的過程被稱為"序列化"(Serialization),而它的逆過程則可被稱為"反序列化"(Deserialization)。

  .Net架構對序列化機制具有非常好的支援,它提供了兩個名字空間(namespace):System.Runtime.Serialization和System.Runtime.Serialization.Formatters以完成序列化機制的大部分功能。系列化這項技術可以應用在将程式産生的結果資料存儲到檔案系統中,但是它更主要的應用是在于.Net Remoting和Web服務的實作上。

  序列化機制的實作是依靠格式器(Formatter)而完成的,它是一個從System.Runtime.Serialization.IFormatter繼承下來的類的對象。格式器完成了将程式資料轉化到能被存儲并傳輸的格式的工作,同時也完成了将資料轉化回來的工作。.Net架構為程式員提供了兩種類型的格式器,一種通常是應用于桌面類型的應用程式的,它一個是System.Runtime.Serialization.Formatters.Binary.BinaryFormatter類的對象,而另一種則更主要的應用于.Net Remoting和XML Web服務等領域的,它一個是System.Runtime.Serialization.Formatters.Soap.SoapFormatter類的對象。從它們的名稱來看,我們不妨将它們分别稱為二進制格式器和XML格式器。

  

  下面我先向大家介紹兩種不同的格式器,分别用它們如何實作序列化機制和反序列化機制,請看下面的代碼:

<a></a>

從上面的代碼我們可以發現無論運用哪種格式器,其基本的過程都是一樣的,而且都是非常容易實作的,唯一的不同就是定義格式器的類型不同。不過在實際的應用中,二進制格式器往往應用于一般的桌面程式和網絡通訊程式中,而XML格式器禀承了XML技術的優點,大多數被應用于.Net Remoting和XML Web服務等領域。下面我們來分析一下兩種格式器各自的優點。

  二進制序列化的優點:

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

  2. 性能非常好。

  XML序列化的優點:

  1. 互操作性好;

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

  3. 可讀性強。

  通過分析上面的代碼,我們知道了選擇二進制序列化的方式還是選擇XML序列化的方式僅僅是對不同的格式器進行選擇而已。你可以根據實際的需要選擇相應的格式器完成序列化和反序列化工作。同時請注意,代碼中的序列化函數和反序列化函數僅僅是在調用Serialize()和Deserialize()這兩個核心函數上産生了差别,即它們的參數不同。是以以上的代碼完成了一些最最基本但是很重要的功能,你可以将它們運用在你的程式中,或是将其進行适當擴充以滿足程式的特定需要。

  如果你要對一個對象進行序列化,那麼你必須将它的類型标記為[Serializable()],該操作是通過SerializableAttribute屬性來實作的。将SerializableAttribute屬性應用于一種資料類型可表明該資料類型的執行個體可以被序列化。如果正在序列化的對象圖中的任何類型未應用SerializableAttribute屬性,公共語言運作庫則會引發SerializationException。預設情況下,類型中由SerializableAttribute标記的所有公共和私有字段都會進行序列化,除非該類型實作ISerializable接口來重寫序列化程序(通過實作該接口我們便可以實作将在後面介紹的"自定義序列化")。預設的序列化程序會排除用NonSerializedAttribute屬性标記的字段,即你可以将該類型标記為[NonSerialized()]以表明它是不可以被序列化的。如果可序列化類型的字段包含指針、句柄或其他某些針對于特定環境的資料結構,并且不能在不同的環境中以有意義的方式重建,則最好将NonSerializedAttribute屬性應用于該字段。有關序列化的更多資訊,請參閱System.Runtime.Serialization名字空間中的相關内容。

  下面我給大家介紹一個例子,以顯示如何正确的運用SerializableAttribute屬性和NonSerializedAttribute屬性。該程式中運用到了XML格式器,不過同時給出了二進制格式器為參考(程式中将其用"//"标注),其實作的結果是一樣的。該程式實作的功能是在序列化和反序列化操作前後測試對象因包含了[NonSerialized()]的字段而顯示不同的螢幕列印結果。其代碼如下:

 View Code

  .Net架構為我們提供了兩種方式的序列化:一種為基本序列化、另一種為自定義序列化。值得注意的是,序列化的方式和前面提到的序列化的格式是不同的概念。序列化的方式是指.Net架構将程式的資料轉化為能被存儲并傳輸的格式的實際過程,它是不管程式員運用了何種類型的格式器的(二進制格式器還是XML格式器)。而序列化的格式則指程式的資料是被轉化成二進制格式了還是被轉化成XML格式了。

  完成序列化的最簡單的方法便是讓.Net架構自動為我們完成整個過程,而我們不必去管它内部是如何具體實作的,這種方法便是前面提到的"基本序列化"。在這種方式下,我們需要做的僅僅是将類标記上[Serializable()]屬性。然後.Net架構便調用該類的對象并将它轉化為所需的格式。同時你還可以控制其中的某些字段不被序列化,方法就是前面所述的将該字段标記上[NonSerialized()]屬性。這樣,最最簡單和基本的序列化工作就完成了,不過其内部是如何實作的你是不得而知的,同時你也不能進一步控制序列化過程的程式行為。

  如果你要獲得對序列化的更大的控制權,那麼你就得使用"自定義序列化"的方式。通過使用這種方式,你可以完全的控制類的哪些部分能被序列化而哪些部分不能,同時你還可以控制如何具體的進行序列化。運用該方式的好處就是能克服基本序列化所會遇到的問題。我們在運用基本序列化将一個類的對象序列化完畢并存儲在檔案中後,假設該對象原來有三個字段,如果此時該對象增加了一個字段,那麼再将該對象從檔案中反序列化出來時會發生字段數不一緻的錯誤。這樣的問題是基本序列化所不能解決的,隻能運用自定義序列化的方式來解決。

  在介紹自定義序列化之前,我先給出介紹過程中所要用到的執行個體程式的代碼。這是一個時間安排程式,其中要用到将不同的時間格式進行轉化的操作。是以運用序列化的機制能很好的解決這個問題。

自定義序列化:

  下面我就向大家介紹自定義序列化以及反序列化的具體過程。首先,程式的類必須實作System.Runtime.Serialization.ISerializable接口,該接口的功能就是允許對象控制其自己的序列化和反序列化過程。是以我們得重新定義上面的類:

[Serializable()]

public class ScheduleCustom : System.Runtime.Serialization.ISerializable

  接下來,我們必須對該接口調用GetObjectData()的實作,也即我們必須在上面的類中給出GetObjectData()的具體實作。其函數原型如下:

void GetObjectData(SerializationInfo info, StreamingContext context);

  上面的類中GetObjectData()的具體實作如下:

   然而對于這麼一個簡單的方法,讀者可能不能理會到系列化帶來的強大功能,是以下面我就給這個方法添加一些東西。如果在系列化過程中我們要檢視類型為DateTime的"start"屬性的輸出的話,其結果會是.Net架構預設的格式:

 而對于沒有.Net架構的使用者,或是在其他時間區域内的使用者而言,這麼一個格式的時間可能是非常難以了解的,是以我們有必要将時間的格式轉化為格林威治标準時間格式,于是修改GetObjectData()方法如下:

  這樣一來,我們在系列化過程中檢視"start"屬性時就會得到如下結果:

 同時請注意我們在GetObjectData()方法中添加的一個名為"timeformat"的額外屬性,通過它我們可以友善的知道系列化過程中所使用的時間格式。如果有興趣的話,你還可以從System.Globalization.DateTimeFormatInfo這個名字空間中擷取更多有關時間格式的資訊。

自定義反序列化:

  你可以通過調用一個自定義的構造函數來完成自定義反序列化的操作。該構造函數的定義如下:

public ScheduleCustom (SerializationInfo info,StreamingContext context);

  在上面的類中,我們的ScheduleCustom()方法将完成把時間格式從格林威治标準時間格式反序列化為當地時間的格式的操作,其函數實作如下:

public ScheduleCustom (SerializationInfo info,StreamingContext context) {

 this.start = info.GetDateTime("start").ToLocalTime();

 this.end = info.GetDateTime("end").ToLocalTime();

 this.interval = info.GetInt32("interval");

}

  在完成自定義序列化和自定義反序列化後,我們的時間安排程式變成了如下形式:

總結以上内容,前三部分向大家介紹了.Net架構下系列化機制的一些基本概念和基本的運用方法,讀者在讀完本文後,應該對以下幾個概念有個初步了解:二進制系列化、XML系列化、基本序列化和自定義系列化,并應能夠完成一些基本的系列化應用。最後,希望大家能合理有效的運用系列化機制并發揮它的功效以更好地滿足實際工作需要。

可以使用.net提供的序列化和反序列化方法來實作,你可将對象序列化成XML字元串,然後存入資料庫中,當你要使用對象的時候,再把資料庫中儲存字元串反序列化成對象就可以使用了,以下為示例代碼:

建立項目

1.      添加一個名為RWTest的表到 SQL Server MYTest 資料庫。 表字段設定如下:

a.      唯一辨別字段名稱為"ID",類型為Int。

b.      名稱為"Description"的VarChar類型的字段,字段長度為50。

c.      名稱為"Data" 的varbinary(Max) 類型的字段。

2.      啟動 Visual Studio .NET, 并建立一個新的 Visual C# Windows 應用程式項目。

3.      從工具欄中拖兩個Button 控件到預設窗體, Form1。

4.      在屬性視窗中修改Name為buttonFileToDB, Text 屬性為從檔案儲存到資料庫, 然後修改Name為buttonDBToFile ,Text 屬性為從資料庫儲存到檔案。

參考文章

沒有整理與歸納的知識,一文不值!高度概括與梳理的知識,才是自己真正的知識與技能。 永遠不要讓自己的自由、好奇、充滿創造力的想法被現實的架構所束縛,讓創造力自由成長吧! 多花時間,關心他(她)人,正如别人所關心你的。理想的騰飛與實作,沒有别人的支援與幫助,是萬萬不能的。

   本文轉自wenglabs部落格園部落格,原文連結:http://www.cnblogs.com/arxive/p/6146875.html,如需轉載請自行聯系原作者