.Net 中的序列化与反序列化 (转)
?? 一、概述
??? 當(dāng)兩個(gè)進(jìn)程在進(jìn)行遠(yuǎn)程通信時(shí),彼此可以發(fā)送各種類型的數(shù)據(jù)。無論是何種類型的數(shù)據(jù),都會(huì)以二進(jìn)制序列的形式在網(wǎng)絡(luò)上傳送。發(fā)送方需要把這個(gè)對象轉(zhuǎn)換為字節(jié)序列,才能在網(wǎng)絡(luò)上傳送;接收方則需要把字節(jié)序列再恢復(fù)為對象。
??? 把對象轉(zhuǎn)換為字節(jié)序列的過程稱為對象的序列化。
??? 把字節(jié)序列恢復(fù)為對象的過程稱為對象的反序列化。
??? 二、對象的序列化主要有兩種用途:
?? 1) 把對象的字節(jié)序列永久地保存到硬盤上,通常存放在一個(gè)文件中;
??? 我們經(jīng)常需要將對象的字段值保存到磁盤中,并在以后檢索此數(shù)據(jù)。盡管不使用序列化也能完成這項(xiàng)工作,但這種方法通常很繁瑣而且容易出錯(cuò),并且在需要跟蹤對象的層次結(jié)構(gòu)時(shí),會(huì)變得越來越復(fù)雜。可以想象一下編寫包含大量對象的大型業(yè)務(wù)應(yīng)用程序的情形,程序員不得不為每一個(gè)對象編寫代碼,以便將字段和屬性保存至磁盤以及從磁 盤還原這些字段和屬性。序列化提供了輕松實(shí)現(xiàn)這個(gè)目標(biāo)的快捷方法。公共語言運(yùn)行時(shí) (CLR) 管理對象在內(nèi)存中的分布,.NET 框架則通過使用反射提供自動(dòng)的序列化機(jī)制。對象序列化后,類的名稱、程序集以及類實(shí)例的所有數(shù)據(jù)成員均被寫入存儲(chǔ)媒體中。對象通常用成員變量來存儲(chǔ)對其他實(shí)例的引用。類序列化后,序列化引擎將跟蹤所有已序列化的引用對象,以確保同一對象不被序列化多次。.NET 框架所提供的序列化體系結(jié)構(gòu)可以自動(dòng)正確處理對象圖表和循環(huán)引用。對對象圖表的唯一要求是,由正在進(jìn)行序列化的對象所引用的所有對象都必須標(biāo)記為 Serializable(請參閱基 本序列化)。否則,當(dāng)序列化程序試圖序列化未標(biāo)記的對象時(shí)將會(huì)出現(xiàn)異常。當(dāng)反序列化已序列化的類時(shí),將重新創(chuàng)建該類,并自動(dòng)還原所有數(shù)據(jù)成員的值。
?? 2) 在網(wǎng)絡(luò)上傳送對象的字節(jié)序列。
???對象僅在創(chuàng)建對象的應(yīng)用程序域中有效。除非對象是從MarshalByRefObject派生得到或標(biāo)記為 Serializable,否則,任何將對象作為參數(shù)傳遞或?qū)⑵渥鳛榻Y(jié)果返回的嘗試都將失敗。如果對象標(biāo)記為 Serializable,則該對象將被自動(dòng)序列化,并從一個(gè)應(yīng)用程序域傳輸至另一個(gè)應(yīng)用程序域,然后進(jìn)行反序列化,從而在第二個(gè)應(yīng)用程序域中產(chǎn)生出該對象的一個(gè)精確副本。此過程通常稱為按值封送。如果對象是從MarshalByRefObject派生得到,則從一個(gè)應(yīng)用程序域傳遞至另一個(gè)應(yīng)用程序域的是對象引用,而不是對象本身。也可以將從MarshalByRefObject派生得到的對象標(biāo)記為Serializable。遠(yuǎn)程使用此對象時(shí),負(fù)責(zé)進(jìn)行序列化并已預(yù)先配置為SurrogateSelector的格式化程序?qū)⒖刂菩蛄谢^程,并用一個(gè)代理替換所有從MarshalByRefObject派生得到的對象。如果沒有預(yù)先配置為SurrogateSelector,序列化體系結(jié)構(gòu)將遵從下面的標(biāo)準(zhǔn)序列化規(guī)則.
???? 三、.NET提供了三種序列化方式
??? [1]、XML Serializer
???? [2]、SOAP Serializer
???? [3]、BinarySerializer
??? 四、基本序列化
??? 要使一個(gè)類可序列化,最簡單的方法是使用 Serializable 屬性對它進(jìn)行標(biāo)記,如下所示:
??? [Serializable]
??? public class MyObject
??? {
??????? public int n1 = 0;
??????? public int n2 = 0;
??????? public String str = null;
??? }
?? [BinarySerializer]
??? 將此類的一個(gè)實(shí)例序列化為一個(gè)文件:
MyObject obj = new MyObject();
obj.n1 = 1;
obj.n2 = 24;
obj.str = "一些字符串";
IFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream("MyFile.bin", FileMode.Create,
FileAccess.Write, FileShare.None);
formatter.Serialize(stream, obj);
stream.Close();
??? 反序列化:
IFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream("MyFile.bin", FileMode.Open,
FileAccess.Read, FileShare.Read);
MyObject obj = (MyObject) formatter.Deserialize(fromStream);
stream.Close();
??[XMLSerializer]
????將此類的實(shí)例序列化成一個(gè)Xml文件.
XmlSerializer ser = new XmlSerializer(obj.GetType());
ser.Serialize(new FileStream(@"users.xml", FileMode.Create), obj);
??? 反序列化:
XmlSerializer serializer = new XmlSerializer(Type.GetType("MyObject"));
MyObject my=(MyObject)serializer.Deserialize(new FileStream(@"users.xml",FileMode.Open));
??? 說明:使用二進(jìn)制格式化程序進(jìn)行序列化。您只需創(chuàng)建一個(gè)要使用的流和格式化程序的實(shí)例,然后調(diào)用格式化程序的 Serialize 方法。流和要序列化的對象實(shí)例作為參數(shù)提供給此調(diào)用。類中的所有成員變量(甚至標(biāo)記為 private 的變量)都將被序列化,但這一點(diǎn)在本例中未明確體現(xiàn)出來。在這一點(diǎn)上,二進(jìn)制序列化不同于只序列化公共字段的 XML 序列化程序。將對象還原到它以前的狀態(tài)也非常容易。首先,創(chuàng)建格式化程序和流以進(jìn)行讀取,然后讓格式化程序?qū)ο筮M(jìn)行反序列化。????
???? [SOAP Serializer]
??? 如果要求具有可移植性,請使用 SoapFormatter。所要做的更改只是將以上代碼中的BinaryFormatter換 SoapFormatter,而 Serialize 和 Deserialize 調(diào)用不變。
總結(jié)
以上是生活随笔為你收集整理的.Net 中的序列化与反序列化 (转)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 网络OS显神威 认识Linux远程桌面控
- 下一篇: 招聘:兼职ASP.NET 开发工程师