.net中物件序列化技術淺談
序列化是將物件狀態轉換為可保持或傳輸的格式的過程。與序列化相對的是反序列化,它將流轉換為物件。這兩個過程結合起來,可以輕鬆地儲存和傳輸資料。例如,可以序列化一個物件,然後使用 HTTP 通過 Internet 在客戶端和伺服器之間傳輸該物件。反之,反序列化根據流重新構造物件。此外還可以將物件序列化後儲存到本地,再次執行的時候可以從本地檔案中“恢復”物件到序列化之前的狀態。
在.net中有提供了幾種序列化的方式:
二進位制序列化
XML序列化
SOAP序列化
二進位制序列化
所謂二進位制序列化,指的是物件序列化之後是二進位制形式的。二進位制序列化是通過BinaryFormatter類來實現的,這個類位於System.Runtime.Serialization.Formatters.Binary名稱空間下。
XML序列化
所謂XML序列化,是指物件序列化之後的結果是XML形式的。儲存XML序列化是通過XmlSerializer 類來實現的, 這個類位於System.Xml.Serialization名稱空間下。
SOAP序列化
所謂SOAP序列化是指物件序列化之後的結果符合SOAP協議,也就是可以通過SOAP協議傳輸(不知道SOAP協議?百度一下吧)。SOAP序列化是通過SoapFormatter類來實現的,這個類位於System.Runtime.Serialization.Formatters.Soap名稱空間下,並且需要注意需要手動新增對這個名稱空間的引用,如下圖所示:
下面編寫一個類用於序列化和反序列化,這個類的程式碼如下:
- using System;
- using System.Collections.Generic;
- using System.Text;
- namespace MySerializeDemo
- {
- [Serializable]
- /// <summary>
- /// 要序列化的物件
- /// 作者:周公
- /// 編寫時間:2009-03-10
- /// </summary>
- public class MyObject
- {
- //[NonSerialized]
- private string name;
- private DateTime birthday;
- private string homePlace;
- /// <summary>
- /// 出生地
- /// </summary>
- public string HomePlace
- {
- get { return homePlace; }
- set { homePlace = value; }
- }
- /// <summary>
- /// 生日
- /// </summary>
- public DateTime Birthday
- {
- get { return birthday; }
- set { birthday = value; }
- }
- /// <summary>
- /// 姓名
- /// </summary>
- public string Name
- {
- get { return name; }
- set { name = value; }
- }
- /// <summary>
- /// 年齡
- /// </summary>
- public int Age
- {
- get { return DateTime.Now.Year - birthday.Year; }
- }
- /// <summary>
- /// override了ToString()方法
- /// </summary>
- /// <returns></returns>
- public override string ToString()
- {
- return string.Format("姓名:{0},生日:{1},出生地:{2},年齡:{3}",name,birthday,homePlace,Age);
- }
- }
- }
下面是分別用上面的三個類進行序列化和反序列化的程式碼:
- using System;
- using System.Collections.Generic;
- using System.Text;
- using System.IO;
- using System.Runtime.Serialization.Formatters;
- using System.Runtime.Serialization.Formatters.Binary;
- using System.Runtime.Serialization.Formatters.Soap;
- using System.Xml.Serialization;
- namespace MySerializeDemo
- {
- class Program
- {
- static void Main(string[] args)
- {
- MyObject obj = new MyObject();
- obj.Birthday = new DateTime(1979, 11, 7);
- obj.HomePlace = "湖北";
- obj.Name = "周公";
- Console.WriteLine("========使用BinaryFormatter類進行序列化和反序列化。====");
- BinarySerialize(obj);
- BinaryDeserialize("C://MyObject.dat");
- Console.WriteLine("========使用SoapFormatter類進行序列化和反序列化。====");
- SOAPSerialize(obj);
- SOAPDeserialize("C://MyObject.soap");
- Console.WriteLine("========使用XmlSerializer類進行序列化和反序列化。====");
- XMLSerialize(obj);
- XMLDeserialize("C://MyObject.xml");
- }
- /// <summary>
- /// 二進位制序列化物件
- /// </summary>
- /// <param name="obj"></param>
- public static void BinarySerialize(MyObject obj)
- {
- using (FileStream stream = new FileStream("C://MyObject.dat", FileMode.Create, FileAccess.Write))
- {
- BinaryFormatter formater = new BinaryFormatter();
- formater.Serialize(stream, obj);
- Console.WriteLine("物件已經被序列化。" + obj.ToString());
- }
- }
- /// <summary>
- /// 二進位制反序列化
- /// </summary>
- /// <param name="fileName"></param>
- public static void BinaryDeserialize(string fileName)
- {
- using (FileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read))
- {
- BinaryFormatter formater = new BinaryFormatter();
- MyObject obj=(MyObject)formater.Deserialize(stream);
- Console.WriteLine("物件已經被反序列化。" + obj.ToString());
- }
- }
- /// <summary>
- /// 二進位制序列化物件
- /// </summary>
- /// <param name="obj"></param>
- public static void SOAPSerialize(MyObject obj)
- {
- using (FileStream stream = new FileStream("C://MyObject.soap", FileMode.Create, FileAccess.Write))
- {
- SoapFormatter formater = new SoapFormatter();
- formater.Serialize(stream, obj);
- Console.WriteLine("物件已經被序列化。" + obj.ToString());
- }
- }
- /// <summary>
- /// 二進位制反序列化
- /// </summary>
- /// <param name="fileName"></param>
- public static void SOAPDeserialize(string fileName)
- {
- using (FileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read))
- {
- SoapFormatter formater = new SoapFormatter();
- MyObject obj = (MyObject)formater.Deserialize(stream);
- Console.WriteLine("物件已經被反序列化。" + obj.ToString());
- }
- }
- /// <summary>
- /// XML序列化
- /// </summary>
- /// <param name="obj"></param>
- public static void XMLSerialize(MyObject obj)
- {
- using (FileStream stream = new FileStream("C://MyObject.xml", FileMode.Create, FileAccess.Write))
- {
- XmlSerializer serializer = new XmlSerializer(typeof(MyObject));
- serializer.Serialize(stream, obj);
- Console.WriteLine("物件已經被序列化。" + obj.ToString());
- }
- }
- /// <summary>
- /// XML反序列化
- /// </summary>
- /// <param name="fileName"></param>
- public static void XMLDeserialize(string fileName)
- {
- using (FileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read))
- {
- XmlSerializer serializer = new XmlSerializer(typeof(MyObject));
- MyObject obj = (MyObject)serializer.Deserialize(stream);
- Console.WriteLine("物件已經被反序列化。" + obj.ToString());
- }
- }
- }
- }
這個程式的執行效果如下:
可見通過上面三個類都能實現將物件序列化儲存,並且都能反序列化還原到物件被序列化之前的狀態(這正是序列化意義所在,能儲存物件執行時的狀態並且還能還原)。如果執行上面的程式碼會在C盤根目錄下建立三個檔案,分別是MyObject.dat、MyObject.soap和MyObject.xml檔案,因為MyObject.dat是二進位制檔案,所以無法檢視檔案的內容,但是我們可以開啟MyObject.soap和MyObject.xml這兩個檔案來比較一下有什麼區別。
MyObject.soap檔案的字尾雖然是.soap,但是還是可以用記事本開啟的,下面是MyObject.soap檔案的內容:
- <SOAP-ENV:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:clr="http://schemas.microsoft.com/soap/encoding/clr/1.0" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
- <SOAP-ENV:Body>
- <a1:MyObject id="ref-1" xmlns:a1="http://schemas.microsoft.com/clr/nsassem/MySerializeDemo/MySerializeDemo%2C%20Version%3D1.0.0.0%2C%20Culture%3Dneutral%2C%20PublicKeyToken%3Dnull">
- <name id="ref-3">周公</name>
- <birthday>1979-11-07T00:00:00.0000000+08:00</birthday>
- <homePlace id="ref-4">湖北</homePlace>
- </a1:MyObject>
- </SOAP-ENV:Body>
- </SOAP-ENV:Envelope>
MyObject.xml檔案也可以用記事本開啟,它的內容如下:
- <?xml version="1.0"?>
- <MyObject xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
- <HomePlace>湖北</HomePlace>
- <Birthday>1979-11-07T00:00:00</Birthday>
- <Name>周公</Name>
- </MyObject>
熟悉SOAP協議的朋友一看MyObject.soap檔案的內容就知道它符合SOAP協議,MyObject.xml檔案毫無疑問是一個符合XML規範的檔案。
對程式碼作幾點說明:
1、如果採用BinaryFormatter類或者SoapFormatter類來實現序列化,則一定要給類加上Serializable屬性,如程式碼中所示:
- [Serializable]
- /// <summary>
- /// 要序列化的物件
- /// 作者:周公
- /// 編寫時間:2009-03-10
- /// </summary>
- public class MyObject
如果不給要序列化的物件加上這個屬性,那麼採用採用BinaryFormatter類或者SoapFormatter類來實現序列化時會報異常,但使用XmlSerializer 類序列化物件時可以不用這個屬性。
2、另外,如果不想序列化某個欄位,可以給其加上NonSerialized屬性,這樣在序列化時就不會儲存這個這個欄位的值了,比如不想序列化name這個欄位,可以如下寫程式碼:
- …//其它程式碼
- //[NonSerialized]
- private string name;
- …//其它程式碼
再次執行剛才的程式會得到如下效果:
看有黃色底線部分,因為name欄位不被序列化,所以通過二進位制序列化和SOAP序列化之後再反序化就得不到原來的值了。
3、最後還需要說明一點的是,SoapFormatter類在.net3.5開始已經過時了,微軟建議使用BinaryFormatter類來序列化和反序列化了。
轉貼於: http://blog.csdn.net/zhoufoxcn/article/details/3978874
相關文章
- 淺談.NET技術公司的實習生培養
- 序列化物件(.NET中) (轉)物件
- 淺談技術翻譯
- 快取技術淺談快取
- 淺談Java序列化Java
- 一起談.NET技術,淺談ASP.NET4中構造HTML5視訊控制元件ASP.NETHTML控制元件
- IPSECVPN技術淺談
- 淺談程序隱藏技術
- 談談 JAVA 的物件序列化Java物件
- 淺談動態追蹤技術
- 淺談API HOOK技術(一) (轉)APIHook
- 淺談API HOOK技術(二) (轉)APIHook
- 技術分享| 淺談IM 產品中的“縮圖”功能
- 淺談活動中臺系統技術債管理實踐
- 淺談LocalCache | 京東雲技術團隊
- 淺談JS中物件的淺複製和深複製JS物件
- 淺談RASP技術攻防之基礎篇
- 技術分享 | 淺談一下大頁
- 淺談Android主流熱修復技術Android
- 好程式設計師技術分享淺談JavaScript中的閉包程式設計師JavaScript
- 淺談公司的技術方向 Java 與 .Net 的分工合作,一個公司的整體技術定位Java
- .NET物件的XML序列化和反序列化物件XML
- 淺談JS物件導向JS物件
- 得物技術淺談深入淺出的Redis分散式鎖Redis分散式
- Laikelib淺談區塊鏈技術架構AI區塊鏈架構
- 技術分享| 淺談排程平臺設計
- 淺談健康技術社群與微軟MVP打造之旅微軟MVP
- 一文淺談“讀寫分離”技術
- 淺談移動應用的技術選型
- 淺談物件導向中的一些主要思想物件
- .NET 中Newtonsoft的使用 自定義物件的序列化物件
- 淺談加密技術加密
- 淺談Array --JavaScript內建物件JavaScript物件
- 淺談.NET 6 中 gRPC 的最新功能RPC
- 談談技術人成長中的軟技能
- 淺談技術管理之日式管理的殊途同歸
- 大齡碼農那些事——淺談技術變現
- 淺談Layer2技術的商業化落地