標籤:des blog http color 使用 io strong ar 問題
這篇隨筆對應的.Net命名空間是System.Xml.Serialization;文中的範例程式碼需要引用這個命名空間。
為什麼要做序列化和還原序列化?.Net程式執行時,對象都駐留在記憶體中;記憶體中的對象如果需要傳遞給其他系統使用;或者在關機時需要儲存下來以便下次再次啟動程式使用就需要序列化和還原序列化。 範圍:
本文只介紹xml序列化,其實序列化可以是二進位的序列化,也可以是其他格式的序列化。 看一段最簡單的Xml序列化代碼
| 123456789101112 |
class Program{ static void Main(string[] args) { int i = 10; //聲明Xml序列化對象執行個體serializer XmlSerializer serializer = new XmlSerializer(typeof(int)); //執行序列化並將序列化結果輸出到控制台 serializer.Serialize(Console.Out, i); Console.Read(); }} |
上面代碼對int i進行了序列化,並將序列化的結果輸出到了控制台,輸出結果如下
<?xml version="1.0" encoding="gb2312"?><int>10</int>
可以將上述序列化的xml進行還原序列化,如下代碼
static void Main(string[] args){ using (StringReader rdr = new StringReader(@"<?xml version=""1.0"" encoding=""gb2312""?><int>10</int>")) { //聲明序列化對象執行個體serializer XmlSerializer serializer = new XmlSerializer(typeof(int)); //還原序列化,並將還原序列化結果值賦給變數i int i = (int)serializer.Deserialize(rdr); //輸出還原序列化結果 Console.WriteLine("i = " + i); Console.Read(); }}
以上代碼用最簡單的方式說明了xml序列化和還原序列化的過程,.Net系統類別庫為我們做了大量的工作,序列化和還原序列化都非常簡單。但是在現實中業務需求往往比較複雜,不可能只簡單的序列化一個int變數,顯示中我們需要對複雜類型進行可控制的序列化。
自訂對象的Xml序列化:
System.Xml.Serialization命名空間中有一系列的屬性類別,用來控制複雜類型序列化的控制。例如XmlElementAttribute、XmlAttributeAttribute、XmlArrayAttribute、XmlArrayItemAttribute、XmlRootAttribute等等。
看一個小例子,有一個自訂類Cat,Cat類有三個屬性分別為Color,Saying,Speed。
namespace UseXmlSerialization{ class Program { static void Main(string[] args) { //聲明一個貓咪對象 var c = new Cat { Color = "White", Speed = 10, Saying = "White or black, so long as the cat can catch mice, it is a good cat" }; //序列化這個對象 XmlSerializer serializer = new XmlSerializer(typeof(Cat)); //將對象序列化輸出到控制台 serializer.Serialize(Console.Out, c); Console.Read(); } } [XmlRoot("cat")] public class Cat { //定義Color屬性的序列化為cat節點的屬性 [XmlAttribute("color")] public string Color { get; set; } //要求不序列化Speed屬性 [XmlIgnore] public int Speed { get; set; } //設定Saying屬性序列化為Xml子項目 [XmlElement("saying")] public string Saying { get; set; } }}
可以使用XmlElement指定屬性序列化為子節點(預設情況會序列化為子節點);或者使用XmlAttribute特性制定屬性序列化為Xml節點的屬性;還可以通過XmlIgnore特性修飾要求序列化程式不序列化修飾屬性。
對象數組的Xml序列化:
數組的Xml序列化需要使用XmlArrayAttribute和XmlArrayItemAttribute;XmlArrayAttribute指定數組元素的Xml節點名,XmlArrayItemAttribute指定數組元素的Xml節點名。
如下程式碼範例:
/*玉開技術部落格 http://www.cnblogs.com/yukaizhao */using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Xml.Serialization;namespace UseXmlSerialization{ class Program { static void Main(string[] args) { //聲明一個貓咪對象 var cWhite = new Cat { Color = "White", Speed = 10, Saying = "White or black, so long as the cat can catch mice, it is a good cat" }; var cBlack = new Cat { Color = "Black", Speed = 10, Saying = "White or black, so long as the cat can catch mice, it is a good cat" }; CatCollection cc = new CatCollection { Cats = new Cat[] { cWhite,cBlack} }; //序列化這個對象 XmlSerializer serializer = new XmlSerializer(typeof(CatCollection)); //將對象序列化輸出到控制台 serializer.Serialize(Console.Out, cc); Console.Read(); } } [XmlRoot("cats")] public class CatCollection { [XmlArray("items"),XmlArrayItem("item")] public Cat[] Cats { get; set; } } [XmlRoot("cat")] public class Cat { //定義Color屬性的序列化為cat節點的屬性 [XmlAttribute("color")] public string Color { get; set; } //要求不序列化Speed屬性 [XmlIgnore] public int Speed { get; set; } //設定Saying屬性序列化為Xml子項目 [XmlElement("saying")] public string Saying { get; set; } }}
以上代碼將輸出:
<?xml version="1.0" encoding="gb2312"?><cats xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <items> <item color="White"> <saying>White or black, so long as the cat can catch mice, it is a goodcat</saying> </item> <item color="Black"> <saying>White or black, so long as the cat can catch mice, it is a goodcat</saying> </item> </items></cats>
XmlSerializer記憶體流失問題:
多謝chenlulouis,仔細看了下msdn,確實存在泄漏的情況,msdn說明如下:
動態產生的程式集
為了提高效能,XML 序列化基礎結構將動態產生程式集,以序列化和還原序列化指定類型。此基礎結構將尋找並重複使用這些程式集。此行為僅在使用以下建構函式時發生:
XmlSerializer(Type)
XmlSerializer.XmlSerializer(Type, String)
如果使用任何其他建構函式,則會產生同一程式集的多個版本,且絕不會被卸載,這將導致記憶體流失和效能降低。最簡單的解決方案是使用先前提到的兩個建構函式的其中一個。否則,必須在 Hashtable 中緩衝程式集,如以下樣本中所示。
也就是說我們在使用XmlSerializer序列化,初始化XmlSerializer對象時最好使用下面兩個建構函式否則會引起記憶體流失。
XmlSerializer(Type)
XmlSerializer.XmlSerializer(Type, String)
C#處理Xml的相關隨筆:
XmlSerializer 對象的Xml序列化和還原序列化,XMLROOT別名設定