1. 程式人生 > >c# 序列化與反序列化

c# 序列化與反序列化

  序列化又稱序列化,是.NET執行時環境用來支援使用者定義型別的流化的機制。其目的是以某種儲存形成使自定義物件持久化,或者將這種物件從一個地方傳輸到另一個地方。    .NET框架提供了兩種序列化的方式:1、是使用BinaryFormatter進行序列化;2、使用SoapFormatter進行序列化;3、使用XmlSerializer進行序列化。第一種方式提供了一個簡單的二進位制資料流以及某些附加的型別資訊,而第二種將資料流格式化為XML儲存;第三種其實和第二種差不多也是XML的格式儲存,只不過比第二種的XML格式要簡化很多(去掉了SOAP特有的額外資訊)。    可以使用[Serializable]屬性將類標誌為可序列化的。如果某個類的元素不想被序列化,1、2可以使用

[NonSerialized]屬性來標誌,2、可以使用[XmlIgnore]來標誌。     1、使用BinaryFormatter進行序列化    下面是一個可序列化的類:     

using System;using System.Data;using System.Configuration;using System.Web;using System.Web.Security;using System.Web.UI;using System.Web.UI.WebControls;using System.Web.UI.WebControls.WebParts;using System.Web.UI.HtmlControls;

using System.IO;using System.Runtime.Serialization.Formatters.Binary;/// <summary>/// ClassToSerialize 的摘要說明/// </summary>[Serializable]public class ClassToSerialize{    public int id = 100;    public string name = "Name";    [NonSerialized]    public string Sex = "";}

    下面是序列化和反序列化的方法:     

public

 void SerializeNow()    {        ClassToSerialize c = new ClassToSerialize();        FileStream fileStream = new FileStream("c:\\temp.dat", FileMode.Create);        BinaryFormatter b = new BinaryFormatter();        b.Serialize(fileStream, c);        fileStream.Close();    }    public void DeSerializeNow()    {        ClassToSerialize c = new ClassToSerialize();        c.Sex = "kkkk";        FileStream fileStream = new FileStream("c:\\temp.dat", FileMode.Open, FileAccess.Read, FileShare.Read);        BinaryFormatter b = new BinaryFormatter();        c = b.Deserialize(fileStream) as ClassToSerialize;           Response.Write(c.name);        Response.Write(c.Sex);        fileStream.Close();    }

    呼叫上述兩個方法就可以看到序列化的結果:Sex屬性因為被標誌為[NonSerialized],故其值總是為null。     2、使用SoapFormatter進行序列化    和BinaryFormatter類似,我們只需要做一下簡單修改即可:    a.將using語句中的.Formatter.Binary改為.Formatter.Soap;    b.將所有的BinaryFormatter替換為SoapFormatter.    c.確保報存檔案的副檔名為.xml    經過上面簡單改動,即可實現SoapFormatter的序列化,這時候產生的檔案就是一個xml格式的檔案。     3、使用XmlSerializer進行序列化    關於格式化器還有一個問題,假設我們需要XML,但是不想要SOAP特有的額外資訊,那麼我們應該怎麼辦呢?有兩中方案:要麼編寫一個實現IFormatter介面的類,採用的方式類似於SoapFormatter類,但是沒有你不需要的資訊;要麼使用庫類XmlSerializer,這個類不使用Serializable屬性,但是它提供了類似的功能。    如果我們不想使用主流的序列化機制,而想使用XmlSeralizer進行序列化我們需要做一下修改:    a.新增System.Xml.Serialization名稱空間。    b.Serializable和NoSerialized屬性將被忽略,而是使用XmlIgnore屬性,它的行為與NoSerialized類似。    c.XmlSeralizer要求類有個預設的構造器,這個條件可能已經滿足了。    下面看示例:    要序列化的類:     

using System;using System.Data;using System.Configuration;using System.Web;using System.Web.Security;using System.Web.UI;using System.Web.UI.WebControls;using System.Web.UI.WebControls.WebParts;using System.Web.UI.HtmlControls;using System.Xml.Serialization;[Serializable]public class Person{    private string name;    public string Name    {        get        {            return name;        }        set        {            name = value;        }    }    public string Sex;    public int Age = 31;    public Course[] Courses;    public Person()    {    }    public Person(string Name)    {        name = Name;        Sex = "";    }}[Serializable]public class Course{    public string Name;    [XmlIgnore]    public string Description;    public Course()    {    }    public Course(string name, string description)    {        Name = name;        Description = description;    }}  

    序列化和反序列化方法:

public void XMLSerialize()    {        Person c = new Person("cyj");        c.Courses = new Course[2];        c.Courses[0= new Course("英語""交流工具");        c.Courses[1= new Course("數學","自然科學");        XmlSerializer xs = new XmlSerializer(typeof(Person));        Stream stream = new FileStream("c:\\cyj.XML",FileMode.Create,FileAccess.Write,FileShare.Read);        xs.Serialize(stream,c);        stream.Close();    }    public void XMLDeserialize()    {        XmlSerializer xs = new XmlSerializer(typeof(Person));        Stream stream = new FileStream("C:\\cyj.XML",FileMode.Open,FileAccess.Read,FileShare.Read);        Person p = xs.Deserialize(stream) as Person;        Response.Write(p.Name);        Response.Write(p.Age.ToString());        Response.Write(p.Courses[0].Name);        Response.Write(p.Courses[0].Description);        Response.Write(p.Courses[1].Name);        Response.Write(p.Courses[1].Description);        stream.Close();    }

這裡Course類的Description屬性值將始終為null,生成的xml文件中也沒有該節點,如下圖:

<?xml version="1.0"?><Person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">  <Sex></Sex>  <Age>31</Age>  <Courses>    <Course>      <Name>英語</Name>      <Description>交流工具</Description>    </Course>    <Course>      <Name>數學</Name>      <Description>自然科學</Description>    </Course>  </Courses>  <Name>cyj</Name></Person>