序列化(Serialization)是.NET平台最酷的特性之一。利用序列化技術,可以實現對象的備份和還原。序列化可以將內存中的對象(或對象圖)序列化為數據流,並保存到磁盤上進行持久化;還可以將數據流反序列化為對象,實現對象的還原。序列化技術在分布式系統的數據傳輸中得到充分的利用,如:XML Web Service 利用XML序列化實現跨平台,.Net Remoting 則用到了二進制序列化和SOAP序列化。
.NET Compact Framework 2.0 支持XML序列化,不支持二進制序列化和SOAP序列化。而 .NET Compact Framework 1.0 連XML序列化都不支持。不過 OpenNETCF 1.x 為 .Net CF 1.0 實現了一個XML序列化的類,這個類在 OpenNETCF.XML.dll 程序集中可以找到。
2.XML 序列化
在 .NET CF 2.0 中使用XML序列化很簡單,跟 .Net Framework 中的一樣。
// XML序列化 Customer 數組
using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
{
Customer[] customers = GetCustomers(); //從數據庫或遠程服務器獲取客戶
System.Xml.Serialization.XMLSerializer ser =new System.Xml.Serialization.XMLSerializer(typeof(Customer));
ser.Serialize(ms, customers);byte[] buffer = ms.ToArray();
// 獲取XML文檔的內容
string XML = System.Text.Encoding.ASCII.GetString(buffer , 0, buffer .Length);
}
// XML反序列化 Customer 數組
using (System.IO.MemoryStream ms = new System.IO.MemoryStream(buffer))
{
System.Xml.Serialization.XMLSerializer ser =new System.Xml.Serialization.XMLSerializer(typeof(Customer));
Customer[] customers = ser.Deserialize(ms) as Customer[];
}
以上示例將對象序列化後,寫入內存流中。你可以換成文件流(FileStream),這樣就可以實現對象的持久化。
3.二進制序列化
從理論上說,二進制序列化無論是性能還是序列化後的數據流大小都比XML序列化更具優勢,這個我曾經在《實戰 Web Service 壓縮傳輸》的PPT和Demo 中深入分析過。.NET CF 2.0 並沒有提供二進制序列化的類,如果你想在 .Net CF 2.0 中進行二進制序列化,可以通過第三方的開源組件 CompactFormatter 來實現。由於CompactFormatter 同時支持 .NET CF 和 .Net Framework,我們可以將 CompactFormatter 序列化後的數據流可以轉換為 byte[],並傳輸到服務器後進行反序列化。
今天我簡單介紹一下 CompactFormatter 的使用,用來跟上面的XML序列化進行比較。
為了讓一個實體類能夠被 CompactFormatter 序列化,首先需要將這個實體類加上[CompactFormatter.Attributes.Serializable()] 特性。
$False$[CompactFormatter.Attributes.Serializable()]
public class Customer {
public Customer() { }
}
然後重寫 Equals 方法。
public override bool Equals(object obj)
{
if (!obj.GetType().Equals(typeof(Customer)))
{
return false;
}
else
{
Customer answer = (Customer)obj;
return (answer.ID == ID && answer.Name == Name);
}
}
就如上面的代碼中,我將實體類 Customer 加上 [CompactFormatter.Attributes.Serializable()] 特性,並重寫了它的 Equals 方法,現在可以使用 CompactFormatter 進行序列化了。
// 二進制序列化 Customer 數組
using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
{
CompactFormatter.CompactFormatter ser = new CompactFormatter.CompactFormatter();
ser.Serialize(ms, customers);byte[] buffer = ms.ToArray();
}
// 二進制反序列化 Customer 數組
using (System.IO.MemoryStream ms = new System.IO.MemoryStream(buffer))
{
CompactFormatter.CompactFormatter ser = new CompactFormatter.CompactFormatter();
customers = ser.Deserialize(ms) as Customer[];
}
4.序列化示例
為了比較 .Net CF 2.0 下的XML序列化和 CompactFormatter 的二進制序列化,我做了一個示例,可以用它來測試兩種序列化的性能。我會用兩種序列化方法對一個包含1000個 Customer 對象的數組進行序列化和反序列化,並記錄兩種方法各自耗費的時間和序列化後數據流的字節大小。
序列化性能測試
具體操作是在 Visual Studio 2005 中采用調試模式將示例程序部署到 Pocket PC 2003 仿真器(最新的V2版本)中並運行。先執行XML序列化,接著執行XML反序列化,然後退出程序。在調試模式下重新啟動示例程序,先後執行二進制序列化和二進制反序列化。測試結果如下:
XML序列化
字節數:207870
耗時:6秒
XML反序列化
耗時:4秒
二進制序列化
字節數:200867
耗時:3秒
二進制反序列化
耗時:2秒
從測試結果看,CompactFormatter 的二進制序列化速度比XML序列化要快1倍,反序列化也是快1倍。但是序列化後的數據流大小卻相差不多,這點我有點失望。
5.總結
在現實應用中,CompactFormatter 可以搭配 SharpZipLib 和 WS-Attachment 使用,從而實現低速網絡下(GPRS/CDMA)的高性能數據傳輸。
示例代碼下載:SerializationMobile.rar