c#序列化及反序列化(三種方式)

一:BinaryFormatter序列化

序列化簡單點來理解就是把內存的東西寫到硬盤中,當然也可以寫到內存中(這個內容我會在後面寫一個例子).而反序列化就是從硬盤中把信息讀到內存中.就這麼簡單,呵呵,現在來看下面的例子吧!

在這篇文章中我將使用BinaryFormatter序列化類Book作爲例子,希望大家能從例子中深刻體會什麼是序列化.

定義類Book:

[Serializable]
public class Book
{
    string name;
    float      price;
    string author;

    public Book(string bookname, float bookprice, string bookauthor)
    {
     name = bookname;
     price = bookprice;
     author = bookauthor;
    }
}

在類的上面增加了屬性:Serializable.(如果不加這個屬性,將拋出SerializationException異常).

通過這個屬性將Book標誌爲可以序列化的.當然也有另一種方式使類Book可以序列化,那就是實行ISerializable接口了.在這裏大家要注意了:Serializable屬性是不能被繼承的咯!!!

如果你不想序列化某個變量,該怎麼處理呢?很簡單,在其前面加上屬性[NonSerialized] .比如我不想序列化

string author;

那我只需要

[NonSerialized]

string author;

好了,現在就告訴大家怎麼實現序列化:

我們使用namespace:

using System;

using System.IO;

using System.Runtime.Serialization.Formatters.Binary;

首先創建Book實例,like this:  

Book book = new Book("Day and Night", 30.0f, "Bruce");

接着當然要創建一個文件了,這個文件就是用來存放我們要序列化的信息了.

FileStream fs = new FileStream(@"C:/book.dat", FileMode.Create);

序列化的實現也很簡單,like this:

      BinaryFormatter formatter = new BinaryFormatter();
      formatter.Serialize(fs, book);

很簡單吧!現在我列出整個原代碼,包括反序列化.

    static void Main(string[] args)
    {
     Book book = new Book("Day and Night", 30.0f, "Bruce");

     using(FileStream fs = new FileStream(@"C:/book.dat", FileMode.Create))
     {
      BinaryFormatter formatter = new BinaryFormatter();
      formatter.Serialize(fs, book);
     }

     book = null;

     using(FileStream fs = new FileStream(@"C:/book.dat", FileMode.Open))
     {
      BinaryFormatter formatter = new BinaryFormatter();
      book = (Book)formatter.Deserialize(fs);//
在這裏大家要注意咯,他的返回值是object
     }
    }


二、SoapFormatter序列化方式 
調用序列化和反序列化的方法和上面比較類似,我就不列出來了,主要就看看SoapSerialize類 
SoapSerialize類 
using System; 
using System.Collections.Generic; 
using System.Text; 
using System.IO; 
using System.Runtime.Serialization.Formatters.Soap; 

namespace SerializableTest 

     public class SoapSerialize 
     { 
         string strFile = /"c:////book.soap/"; 

         public void Serialize(Book book) 
         { 
             using (FileStream fs = new FileStream(strFile, FileMode.Create)) 
             { 
                 SoapFormatter formatter = new SoapFormatter(); 
                 formatter.Serialize(fs, book); 
             } 
         } 

         public Book DeSerialize() 
         { 
             Book book; 
             using (FileStream fs = new FileStream(strFile, FileMode.Open)) 
             { 
                 SoapFormatter formatter = new SoapFormatter(); 
                 book = (Book)formatter.Deserialize(fs);

 


             } 
             return book; 
         } 
     } 

主要就是調用System.Runtime.Serialization.Formatters.Soap空間下的SoapFormatter類進行序列化和反序列化,使用之前需要應用System.Runtime.Serialization.Formatters.Soap.dll(.net自帶的) 
序列化之後的文件是Soap格式的文件(簡單對象訪問協議(Simple Object Access Protocol,SOAP),是一種輕量的、簡單的、基於XML的協議,它被設計成在WEB上交換結構化的和固化的信息。 SOAP 可以和現存的許多因特網協議和格式結合使用,包括超文本傳輸協議(HTTP),簡單郵件傳輸協議(SMTP),多用途網際郵件擴充協議(MIME)。它還支持從消息系統到遠程過程調用(RPC)等大量的應用程序。SOAP使用基於XML的數據結構和超文本傳輸協議(HTTP)的組合定義了一個標準的方法來使用Internet上各種不同操作環境中的分佈式對象。) [Page]
調用反序列化之後的結果和方法一相同 


三、XML序列化方式 
調用序列化和反序列化的方法和上面比較類似,我就不列出來了,主要就看看XmlSerialize類 
XmlSerialize類 
using System; 
using System.Collections.Generic; 
using System.Text; 
using System.IO; 
using System.Xml.Serialization; 

namespace SerializableTest 

     public class XmlSerialize 
     { 
         string strFile = /"c:////book.xml/"; 

         public void Serialize(Book book) 
         { 
             using (FileStream fs = new FileStream(strFile, FileMode.Create)) 
             { 
                 XmlSerializer formatter = new XmlSerializer(typeof(Book)); 
                 formatter.Serialize(fs, book); 
             } 
         } 

         public Book DeSerialize() 
         { 
             Book book; 
             using (FileStream fs = new FileStream(strFile, FileMode.Open)) 
             { 
                 XmlSerializer formatter = new XmlSerializer(typeof(Book)); 
                 book = (Book)formatter.Deserialize(fs); 
             } 
             return book; 
         } 
     } 

從這三個測試類我們可以看出來其實三種方法的調用方式都差不多,只是具體使用的類不同 
xml序列化之後的文件就是一般的一個xml文件: 
book.xml 
<?xml version=/"1.0/"?> 
<Book xmlns:xsi=/"http://www.w3.org/2001/XMLSchema-instance/" xmlns:xsd=/"http://www.w3.org/2001/XMLSchema/"> 
   <strBookName>C#強化</strBookName> 
   <strBookPwd>*****</strBookPwd> 
   <alBookReader> 
     <anyType xsi:type=/"xsd:string/">gspring</anyType> 
     <anyType xsi:type=/"xsd:string/">永春</anyType> 
   </alBookReader> 
   <BookID>1</BookID> 
</Book>輸出截圖如下: 

也就是說採用xml序列化的方式只能保存public的字段和可讀寫的屬性,對於private等類型的字段不能進行序列化 

關於循環引用: 
比如在上面的例子Book類中加入如下一個屬性: 
         public Book relationBook; 
在調用序列化時使用如下方法: 
             Book book = new Book(); 
             book.BookID = /"1/"; [Page]
             book.alBookReader.Add(/"gspring/"); 
             book.alBookReader.Add(/"永春/"); 
             book.strBookName = /"C#強化/"; 
             book.strBookPwd = /"*****/";

            book.SetBookPrice(/"50.00/"); 

             Book book2 = new Book(); 
             book2.BookID = /"2/"; 
             book2.alBookReader.Add(/"gspring/"); 
             book2.alBookReader.Add(/"永春/"); 
             book2.strBookName = /".NET強化/"; 
             book2.strBookPwd = /"*****/"; 
             book2.SetBookPrice(/"40.00/"); 

             book.relationBook = book2; 
             book2.relationBook = book; 
             BinarySerialize serialize = new BinarySerialize(); 
             serialize.Serialize(book);這樣就會出現循環引用的情況,對於BinarySerialize和SoapSerialize可以正常序列化(.NET內部進行處理了),對於XmlSerialize出現這種情況會報錯:/"序列化類型 SerializableTest.Book 的對象時檢測到循環引用。/"


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章