[.net 面向對象程序設計進階] (9) 序列化(Serialization) (一) 二進制流序列化
本節導讀:
在.NET編程中,經常面向對象處理完以后要轉換成另一種格式傳輸或存儲,這種將對象轉向其他數據格式的過程,即序列化(Serialization)。
與之相反的過程就是反序列化(Deserialization)。掌握和利用好序列化和反序列化的方法,對提高面向編程技術很有益處。
讀前必備:
A.類和類的實例 [.net 面向對象編程基礎] (9) 類和類的實例
B.類的成員 [.net 面向對象編程基礎] (10) 類的成員(字段、屬性、方法)
1. 什么是序列化和反序列化?
序列化(Serialization):序列化是將對象狀態轉換為可保持或傳輸的格式的過程。
反序列化(Deserialization) :與序列化相對的是反序列化,它將流轉換為對象。這兩個過程結合起來,可以輕松地存儲和傳輸數據。
在MFC中儲存或恢復對象的過程即為Serialization,也稱為Persistent(永續生存)。在序列化期間,對象將其當前狀態寫入到臨時或永久性存儲區(存入文件中)。以后,可以通過從存儲區中讀取或反序列化對象的狀態,重新創建該對象。以此達到面向對象中的永續生存。
2. .NET中的序列化技術
.NET Framework 幾種序列化技術,主要有以下幾種:
嚴格來說只有兩種,就是二進制序列化,和使用數據格式協定的序列化(包含XML,SOAP.JSON等)
A. 二進制(流)序列化(BinaryFormatter) -->(C/S方向為主)
二進制序列化保持類型保真度,用於在應用程序的不同調用之間保留對象的狀態。
例如,通過將對象序列化到剪貼板,可在不同的應用程序之間共享對象。您可以將對象序列化到流、磁盤、內存和網絡等等。遠程處理使用序列化“通過值”在計算機或應用程序域之間傳遞對象。
B. XML 序列化(XmlSerializer) -->(B/S C/S通用)
XML序列化僅序列化公共屬性和字段,且不保持類型保真度。對於要提供或使用數據而不限制使用該數據的應用程序時,比較有用的。由於 XML 是一個開放式標准,因此,對於通過 Web 共享數據而言,這是一個很好的選擇。
C. SOAP序列化(SoapFormatter) -->(通用,主要用於WebSerice交換數據)
SOAP同樣是一個開放式標准,這SOAP協議是一個在異構的應用程序之間進行信息交互的理想的選擇
D. WCF協議序列化(DataContractSerializer)-->(B/S方向,主要用於WCF通訊)
F. Json序列化 (DataContractJsonSerializer)-->(B/S移動開發 方向)
Json全稱是 JavaScript 對象表示法(JavaScript Object Notation))是一種輕量級的數據交換方式。
3. 二進制(流)序列化
本節主要介紹二進制(流)序列化
二進制(流)序列化,主要在底層(相對)通訊中使用比較頻繁,我們知道計算機是通過二進制將數據傳輸和存儲到媒介(硬盤等),那么我們在進行面向對象編程中,如何准確快速的將對象實例轉換為二進制流,就是我們這節要介紹的內容。
對象=》二進制流 即二進制流序列化
下面,我還是使用“基礎篇”中“武林高手”的類來 通過“文件流”創建文件。
首先創建數據類及序列化方法,如下:
注意一下:[Serializable]標識
Serializable屬性用來明確表示該類可以被序列化。
同樣的,我們可以用NonSerializable屬性用來明確表示類不能被序列化。
/// <summary> /// 類:武林高手 /// MartialArtsMaster /// </summary> [Serializable] class MartialArtsMaster { /// <summary> /// 編號 /// </summary> public int Id { get; set; } /// <summary> /// 姓名 /// </summary> public string Name { get; set; } /// <summary> /// 年齡 /// </summary> public int Age { get; set; } /// <summary> /// 門派 /// </summary> public string Menpai { get; set; } /// <summary> /// 武學 /// </summary> public string Kungfu { get; set; } /// <summary> /// 級別 /// </summary> public int Level { get; set; } } /// <summary> /// 二進制序列化和反序列化類 /// </summary> public class Serializer { /// <summary> /// 使用二進制序列化對象。 /// </summary> /// <param name="value"></param> /// <returns></returns> public static byte[] SerializeBytes(object value) { if (value == null) return null; var stream = new MemoryStream(); new BinaryFormatter().Serialize(stream, value); //var dto = Encoding.UTF8.GetString(stream.GetBuffer()); var bytes = stream.ToArray(); return bytes; } /// <summary> /// 使用二進制反序列化對象。 /// </summary> /// <param name="bytes"></param> /// <returns></returns> public static object DeserializeBytes(byte[] bytes) { if (bytes == null) return null; //var bytes = Encoding.UTF8.GetBytes(dto as string); var stream = new MemoryStream(bytes); var result = new BinaryFormatter().Deserialize(stream); return result; } }
下面是調用方法:
//本例命名空間 //using System.Runtime.Serialization.Formatters.Binary; //using System.IO; //初始化武林高手 var master = new List<MartialArtsMaster>(){ new MartialArtsMaster(){ Id = 1, Name = "黃蓉", Age = 18, Menpai = "丐幫", Kungfu = "打狗棒法", Level = 9 }, new MartialArtsMaster(){ Id = 2, Name = "洪七公", Age = 70, Menpai = "丐幫", Kungfu = "打狗棒法", Level = 10 }, new MartialArtsMaster(){ Id = 3, Name = "郭靖", Age = 22, Menpai = "丐幫", Kungfu = "降龍十八掌",Level = 10 }, new MartialArtsMaster(){ Id = 4, Name = "任我行", Age = 50, Menpai = "明教", Kungfu = "葵花寶典", Level = 1 }, new MartialArtsMaster(){ Id = 5, Name = "東方不敗",Age = 35, Menpai = "明教", Kungfu = "葵花寶典", Level = 10 }, new MartialArtsMaster(){ Id = 6, Name = "林平之", Age = 23, Menpai = "華山", Kungfu = "葵花寶典", Level = 7 }, new MartialArtsMaster(){ Id = 7, Name = "岳不群", Age = 50, Menpai = "華山", Kungfu = "葵花寶典", Level = 8 } }; //文件流寫入 using (FileStream fs = new FileStream(@"F:\360同步雲盤\360同步雲盤\博客\序列化\master.obj", FileMode.Append)) { var myByte = Serializer.SerializeBytes(master); fs.Write(myByte, 0, myByte.Length); fs.Close(); }; //文件流讀取 using (FileStream fsRead = new FileStream(@"F:\360同步雲盤\360同步雲盤\博客\序列化\master.obj", FileMode.Open)) { int fsLen = (int)fsRead.Length; byte[] heByte = new byte[fsLen]; int r = fsRead.Read(heByte, 0, heByte.Length); var myObj = Serializer.DeserializeBytes(heByte) as List<MartialArtsMaster>; Console.WriteLine("編號---姓名---年齡---門派---武功---等級"); myObj.ForEach(m => Console.WriteLine(m.Id + "---" + m.Name + "---" + m.Age + "---" + m.Menpai + "---" + m.Kungfu + "---" + m.Level) ); }
運行結果如下:
首先是創建的文件master.obj:

讀取運行結果如下:

4.要點:
A.序列化和反序列化的理解:
序列化(Serialization):序列化是將對象狀態轉換為可保持或傳輸的格式的過程。
反序列化(Deserialization) :與序列化相對的是反序列化,它將流轉換為對象。
B. .NET中的序列化技術
注明了主要使用方向,方便小伙伴們有選擇性的學習。
(1)二進制(流)序列化( BinaryFormatter) -->(C/S方向為主)
(2)XML 序列化(XmlSerializer) -->(B/S C/S通用)
(3)SOAP序列化(SoapFormatter -->(通用,主要用於WebSerice交換數據)
(4)WCF協議序列化(DataContractSerializer)-->(B/S方向,主要用於WCF通訊)
(5) Json序列化 (DataContractJsonSerializer)-->(B/S移動開發 方向)
==============================================================================================
<如果對你有幫助,記得點一下推薦哦,如有有不明白或錯誤之處,請多交流>
<對本系列文章閱讀有困難的朋友,請先看《.net 面向對象編程基礎》>
<轉載聲明:技術需要共享精神,歡迎轉載本博客中的文章,但請注明版權及URL>
==============================================================================================

