C#序列化与反序列化详解
什么是序列化以及如何實現序列化?
序列化是通過將對象轉換為字節流,從而存儲對象或將對象傳輸到內存,數據庫或文件的過程。主要用途是保存對象的狀態,包括對象的數據,以便能夠在需要是重建對象。反向過程稱為 反序列化。
?
如上圖所示,對象 object 被序列化為 流,其中不僅包含數據、還包含對象類型的相關信息,如版本、區域性和程序集名稱。然后可以將此流中的內容存儲到數據庫、文件或內存中。
?
序列化的用途:
通過序列化,可以執行如下操作:通過 Web 服務將對象發送到遠程應用程序、在域之間傳遞對象、以 XML 字符串的形式傳遞對象通過防火墻、跨應用程序維護安全性或用戶專屬信息。
?
讓對象可序列化:
需要具有對象、包含已序列化對象的一個流,以及一個 Fromatter。
System.Runtime.Serialization 包含序列化和反序列化對象所必須的類。
將 SerializableAttribute 特性應用于某個類型,以表示此類型的實例可以被序列化,如果對沒有 SerializableAttribute 特性的類型進行序列化,則會引發異常。
如果想讓類中的某個字段不可序列化,可以使用 NonSerializedAttribute 特性。
?
序列化的三種類型--二進制、XML、JSON
可以使用二進制 binary 或 XML 進行序列化,在 二進制序列化中,所有內容都會被序列化,且性能也很好,使用二進制編碼來生成精簡的序列化,可以用于基于存儲或socket的網絡流。
XML 序列化可提高可讀性,以及對象共享和使用的靈活性,XML 序列化將對象的公共字段和屬性或方法的參數和返回值序列化成符合特定 XML 格式的流,
System.Xml.Serialization 包含序列化和反序列化 XML 所需要的類
如果要保存運行程序過程的數據要么保存到數據庫中,要么新建一個普通的文件,然后把數據保存進去.但是這兩者有個缺點就是,不能把原有數據的結構也保存進去.比如一個類中的字段值保存進去后再讀取出來必須再解析下才行.序列化技術讓你省去了解析的過程.保存后再讀取時直接得到一個class
序列化的方式有三種:BinaryFormatter,SoapFormatter,XmlSerializer
1.BinaryFormatter
保存成二進制數據流.用法示例:
using System.IO; using System.Runtime.Serialization.Formatters.Binary; [Serializable] //如果要想保存某個class中的字段,必須在class前面加個這樣attribute(C#里面用中括號括起來的標志符) public class Person { public int age; public string name; [NonSerialized] //如果某個字段不想被保存,則加個這樣的標志 public string secret; }序列化:
classProgram {staticvoid Main(string[] args) { Person person = newPerson(); person.age = 18; person.name = "tom"; person.secret = "i will not tell you"; FileStream stream =newFileStream(@"c:\temp\person.dat",FileMode.Create); BinaryFormatter bFormat =newBinaryFormatter(); bFormat.Serialize(stream, person); stream.Close(); }反序列化:
classProgram { staticvoid Main(string[] args) { Person person = newPerson(); FileStream stream =newFileStream(@"c:\temp\person.dat",FileMode.Open); BinaryFormatter bFormat =newBinaryFormatter(); person = (Person)bFormat.Deserialize(stream); //反序列化得到的是一個object對象.必須做下類型轉換 stream.Close(); Console.WriteLine(person.age + person.name + person.secret); //結果為18tom.因為secret沒有有被序列化. }2.SoapFormatter
把數據保存成xml文件.里面除了保存的內容還有些額外的Soap信息.它的用法和BinaryFormatter一樣.只要把BinaryFormatter都替換成SoapFormatter就行.
把文件名改為person.xml
另外就是添加名稱空間:using System.Runtime.Serialization.Formatters.Soap;
這個名稱空調對就的程序集有時VS沒有自動引用.你必須手動去引用.選中project,右擊選擇Add Reference.在.NET的標簽下選擇
System.Runtime.Serialization.Formatters.Soap.然后點OK.
補充:SOAP(Simple Object Access Protocol )簡單對象訪問協議是在分散或分布式的環境中交換信息的簡單的協議,是一個基于XML的協議,它包括四個部分:SOAP封裝(envelop),封裝定義了一個描述消息中的內容是什么,是誰發送的,誰應當接受并處理它以及如何處理它們的框架;SOAP編碼規則(encoding rules),用于表示應用程序需要使用的數據類型的實例; SOAP RPC表示(RPC representation),表示遠程過程調用和應答的協定;SOAP綁定(binding),使用底層協議交換信息。
3.XmlSerializer
也是保存成XML文件.但沒有其他額外信息.另外它只能保存public類型的字段.而其他兩種類型能保存所有類型的字段.
這里仍使用上面的Person類.
實例1:
添加名稱空間:
using System.IO; using System.Xml.Serialization;序列化:
classProgram {staticvoid Main(string[] args) { Person person = newPerson(); person.age = 18; person.name = "tom"; person.secret = "i will not tell you"; FileStream stream =newFileStream(@"c:\temp\xmlFormat.xml",FileMode.Create); XmlSerializer xmlserilize = newXmlSerializer(typeof(Person)); xmlserilize.Serialize(stream, person); stream.Close(); }反序列化:
classProgram { staticvoid Main(string[] args) { Person person = newPerson(); FileStream stream =newFileStream(@"c:\temp\xmlFormat.xml",FileMode.Open); XmlSerializerxmlserilize = newXmlSerializer(typeof(Person)); person = (Person)xmlserilize.Deserialize(stream); stream.Close(); Console.WriteLine(person.age + person.name + person.secret); }指定 XML 標簽的名字
[XmlRoot(department)] public class Department {public string DeptName { get; set; }[XmlElement("extra")]public DeptExtraInfo DeptExtraInfo { get; set; } }通過在 XmlRoot、XmlElement 后面加上一個括號即可實現,其中XmlRoot用于指定“根”,也就是XML的最上一層的Tag
指定 XML 標簽的屬性
[XmlRoot("department")] public class Department {public string DeptName { get; set; } = "研發部";[XmlAttribute("timestamp")]public int Timestamp = 10; }Timestamp就成為了department這個根節點的timestamp屬性。
實例2:
傳統方法生成xml:(超鏈接)
C#在WINForm程序中創建XML文件
總結
以上是生活随笔為你收集整理的C#序列化与反序列化详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 服务端和客户端证书各种组合下对访问者(浏
- 下一篇: TLS是如何保障数据传输安全(中间人攻击