.net c# 序列化和反序列

來源:互聯網
上載者:User

所謂的序列化就是是將對象轉換為容易傳輸的格式的過程,一般情況下轉化打流檔案,放入記憶體或者IO檔案中。例如,可以序列化一個對象,然後使用 HTTP 通過 Internet 在用戶端和伺服器之間傳輸該對象,或者和其它應用程式共用使用。反之,還原序列化根據流重新構造對象。
  
  .NET內建的有兩種序列化對象的方式,Xml和binary的,XML 序列化不轉換方法、索引器、私人欄位或唯讀屬性(唯讀集合除外)。要序列化對象的所有欄位和屬性(公用的和私人的),請使用 BinaryFormatter,而不要使用 XML 序列化(參見ms-help://MS.NETFramework.v20.chs/dv_fxserialization/html/8c63200d-db63-4a03-a93d-21641623df62.htmXML 和 SOAP 序列化)。

   兩者的程式處理方式基本一致,都是基於原廠模式的,下面我就只說二進位的序列化的方式:
   例如我們有個對象: [Serializable]public class ClassToSerialize{
    public int id=100;
    public string name="Name";
}
  
需要序列化該對象,必須在給該類加上Serializable的屬性,然後建立一個序列化寫入的流:FileStream fileStream = new FileStream("temp.dat", FileMode.Create);然後建立二進位格式器:BinaryFormatter b=new BinaryFormatter();然後是序列化:b.Serialize(fileStream,c);,然後關閉儲存流。(可以見下面的例子)
 
   讀取一個已經被序列化的對象的時候:操作方式一樣,只是FileStream fileStream = new FileStream("temp.dat", FileMode.Open, FileAccess.Read, FileShare.Read);
ClassToSerialize c =(ClassToSerialize)b.Deserialize(fileStream);
然後就可以讀取了,完整的例子是:using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
public class SerialTest{
    public void SerializeNow(){
        ClassToSerialize c=new ClassToSerialize();
        FileStream fileStream = new FileStream("temp.dat", FileMode.Create);

        BinaryFormatter b=new BinaryFormatter();
        b.Serialize(fileStream,c);
        fileStream.Close();
    }
    public void DeSerializeNow(){
        ClassToSerialize c=new ClassToSerialize();
        FileStream fileStream = new FileStream("temp.dat", FileMode.Open, FileAccess.Read, FileShare.Read);
        BinaryFormatter b=new BinaryFormatter();//SoapFormatter
        c=(ClassToSerialize)b.Deserialize(fileStream);
        Console.WriteLine(c.name);
        fileStream.Close();
    }
    public static void Main(string[] s){
        SerialTest st=new SerialTest();
        st.SerializeNow();
        st.DeSerializeNow();
    }
}
[Serializable]
public class ClassToSerialize{
    public int id=100;
    public string name="Name";
}

這就是內建的序列化和反序列的操作,但是,很多情況下,一個對象比較大,而且很多私人的屬性和方法我們不需要,例如在原型模式裡面序列化的話,只需要序列Clone方法和一些屬性,私人的方法無需要,還例如在讀取大規模的IO的時候,讀取操作完全不需要... 這時候就需要自己整合重寫序列的ISerializable介面:

 實現該介面需要兩個注意的,一個就是建構函式,主要是為了反序列,另一個就是GetObjectData,主要是執行序列化,例如我們現在有一個Employee類需要序列化    [Serializable()]    //Set this attribute to all the classes that want to serialize
    public class Employee : ISerializable //derive your class from ISerializable {
        public int EmpId;
        public string EmpName;
        [NonSerialized()]
    public string NoSerialString="NoSerialString-Test";

}
,需要注意的是我這裡的NoSerialString屬性前面有[NonSerialized()],就是說預設並不序列化這個屬性,而是使用預設值 。

 首先是建構函式:        public Employee(SerializationInfo info, StreamingContext ctxt)
        {
            EmpId = (int)info.GetValue("EmployeeId", typeof(int));
            EmpName = (String)info.GetValue("EmployeeName", typeof(string));
            //NoSerialString = (String)info.GetValue("NoSerialString", typeof(string));
        }

然後是序列化方法,就是當寫入流的時候怎麼儲存的:
        public void GetObjectData(SerializationInfo info, StreamingContext ctxt)
        {
            //You can use any custom name for your name-value pair. But make sure you
            // read the values with the same name. For ex:- If you write EmpId as "EmployeeId"
            // then you should read the same with "EmployeeId"
            info.AddValue("EmployeeId", EmpId);
            info.AddValue("EmployeeName", EmpName);
        }

把上面兩個方法寫入到Employee類,然後寫個測試的程式:
public class ObjSerial{
    public static void Main(String[] args){
        Employee mp = new Employee();
        mp.EmpId = 10;
        mp.EmpName = "Omkumar";
        mp.NoSerialString = "你好啊";
               
       //序列化
        Stream stream = File.Open("EmployeeInfo.osl", FileMode.Create);
        BinaryFormatter bformatter = new BinaryFormatter();
               
        Console.WriteLine("Writing Employee Information");
        bformatter.Serialize(stream, mp);
        stream.Close();

 

        mp = null;
       //反序列
        stream = File.Open("EmployeeInfo.osl", FileMode.Open);
        bformatter = new BinaryFormatter();
           
        Console.WriteLine("Reading Employee Information");
        mp = (Employee)bformatter.Deserialize(stream);
        stream.Close();
               
        Console.WriteLine("Employee Id: {0}",mp.EmpId.ToString());
        Console.WriteLine("Employee Name: {0}",mp.EmpName);
        Console.WriteLine("Employee NoSerialString: {0}",mp.NoSerialString);

    }
}

執行的結果是:Writing Employee Information
Reading Employee Information
Employee Id: 10
Employee Name: Omkumar
Employee NoSerialString: NoSerialString-Test
 
 看到Employee NoSerialString:屬性的值沒有,它保持預設值,沒有序列化。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.