C#對象序列化

來源:互聯網
上載者:User

  要讓一個對象支援.Net序列化服務,使用者必須為每一個關聯的類加上[Serializable]特性。如果類中有些成員不適合參與序列化(比如:密碼欄位),可以在這些域前加上[NonSerialized]特性。

  C#支援三種序列化格式:二進位格式(使用BinaryFormatter序列化器)、SOAP格式(使用SoapFormatter序列化器)、XML格式(使用XmlSerializer序列化器)。這三種序列化器的區別如下:

  二進位格式可序列化一個類型的所有可序列化欄位,不管它是公用欄位還是私人欄位。SOAP格式和XML格式僅能序列化公用欄位或擁有公用屬性的私人欄位,未通過屬性公開的私人欄位將被忽略。

  使用二進位格式序列化時,它不僅是將對象的欄位資料進行持久化,也持久化每個類型的完全限定名稱和定義程式集的完整名稱(包括包稱、版本、公開金鑰標記、地區性),這些資料使得在進行二進位格式還原序列化時亦會進行類型檢查。SOAP格式序列化通過使用XML命名空間來持久化原始程式集資訊。而XML格式序列化不會儲存完整的類型名稱或程式集資訊。這便利XML資料表現形式更有終端開放性。如果希望儘可能延伸持久化對象圖的使用範圍時,SOAP格式和XML格式是理想選擇。

  BinaryFormatter和SoapFormatter類型通過實現IFormatter和IRemotingFormatter介面實現序列化。

  IFormatter介面定義了核心的Serialize和Deserialize方法用於序列化和還原序列化。

  IRemotingFormatter介面重載了Serialize和Deserialize方法,使風格更適合分布式持久化。

  範例程式碼:

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization.Formatters.Soap;
using System.IO;
using System.Xml.Serialization;

namespace CollectionSerialize
{
class Program
{
static void Main(string[] args)
{
//檔案名稱
string fileName = "Programmers.dat";

//建立Programmer列表,並添加對象
List<Programmer> list = new List<Programmer>();
list.Add(new Programmer("Coder1", false, "C"));
list.Add(new Programmer("Coder2", false, "C++"));
list.Add(new Programmer("Coder3", false, "Java"));

//建立檔案流
Stream fStream = null;
fStream = FileReset(fStream, fileName);

//使用二進位序列化器
BinaryFormatter binFormat = new BinaryFormatter();
//將list序列化到檔案中
binFormat.Serialize(fStream, list);
//清空列表
list.Clear();
//重設流位置
fStream.Position = 0;
//還原序列化,注意要將結果轉型
list = (List<Programmer>)binFormat.Deserialize(fStream);

//輸出
Print(list);
fStream = FileReset(fStream, fileName);

//使用XML序列化
//注意使用此構造器時必須在第一個參數傳入序列化的類型,第二個參數傳入序列化所涉及的相互關聯類型
XmlSerializer xmlFormat = new XmlSerializer(typeof(List<Programmer>), new Type[] { typeof(Programmer), typeof(Person) });
//還原序列化
xmlFormat.Serialize(fStream, list);
list.Clear();
fStream.Position = 0;
//還原序列化,注意要將結果轉型
list = (List<Programmer>)xmlFormat.Deserialize(fStream);

Print(list);
fStream = FileReset(fStream, fileName);

//使用SOAP序列化
SoapFormatter soapFormat = new SoapFormatter();
//序列化,Soap不能序列化泛型對象,所以只能指定序列化一個Programmer對象
soapFormat.Serialize(fStream, list[0]);
list.Clear();
fStream.Position = 0;
//還原序列化
list.Add((Programmer)soapFormat.Deserialize(fStream));

Print(list);
fStream.Close();

Console.ReadKey();
}

//輸出程式員列表
static void Print(List<Programmer> list)
{
Console.WriteLine("程式員資訊列表:");
foreach (Programmer p in list)
{
Console.WriteLine("姓名:{0} 性別:{1} 程式設計語言:{2}", p.Name, p.Sex.ToString(), p.Language);
}
}

//重設檔案
static FileStream FileReset(Stream fStream, string fileName)
{
//關閉檔案流
if (fStream != null)
{
fStream.Close();
}

//刪除檔案
File.Delete(fileName);
//建立檔案流
return new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None);
}
}

[Serializable] //必須添加序列化特性
public class Person
{
//姓名
public string Name;
//性別
public bool Sex;

//必須提供無參構造器,否則XmlSerializer將出錯
public Person() { }

//建構函式
public Person(string name, bool sex)
{
this.Name = name;
this.Sex = sex;
}
}

[Serializable] //必須添加序列化特性
public class Programmer : Person
{
//程式設計語言
public string Language;

//必須提供無參構造器,否則XmlSerializer將出錯
public Programmer() { }

//建構函式
public Programmer(string name, bool sex, string language)
: base(name, sex)
{
this.Language = language;
}
}
}

  程式運行結果如下:

  需要注意的是:

  1. SoapFormatter不能序列化泛型對象。

  2. XmlSerializer的構造器需要傳入序列化涉及的相互關聯類型資訊。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.