C#對象序列化(3)

來源:互聯網
上載者:User
C#對象序列化(3)作者: 日期:2009-3-14 23:43:39 出處:淘特網
using System;
……………………………………………
//匯入必要的命名空間
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization;
using System.IO;
namespace CustomSerialize
{
public partial class form1 : Form
{
//聲明string類型變數,用於儲存使用者確認的路徑
string fn;       
public form1()
{
InitializeComponent();
}
         private void form1_Load(object sender, EventArgs e)
{
//表單載入時,下面兩個GroupBox容器控制項不可用
this.groupBox2.Enabled = false;
this.groupBox3.Enabled = false;
}
         private void PathBtn_Click(object sender, EventArgs e)
{
//擷取PathTxt的Text屬性值,並賦值給fn變數和PathLabel的Text屬性值
fn = PathTxt.Text;
PathLabel.Text = fn;
//下面兩個GroupBox容器控制項可用
this.groupBox1.Enabled = false;
this.groupBox2.Enabled = true;
//第1個GroupBox容器控制項可用
this.groupBox3.Enabled = true;
}
         private void SerBtn_Click(object sender, EventArgs e)
{
//建立Details類對象Dt
Details Dt = new Details();
//將兩個文字框內容複寫給Dt的兩個屬性
Dt.Name = nametxt.Text;
Dt.NickName = nicknametxt.Text;
//建立IFormatter介面引用,來自於BinaryFormatter類對象
IFormatter Fmt = new BinaryFormatter();
//建立Stream類型引用fs,並傳遞fn作路徑參數
Stream fs = new FileStream(fn, FileMode.Create, FileAccess.Write, FileShare.None);
//調用Fmt的Serialize方法,傳遞fs和Dt參數
Fmt.Serialize(fs, Dt);
//關閉fs對象
fs.Close();
//輸出成功資訊
MessageBox.Show("序列化完成");
}
         private void DeserBtn_Click(object sender, EventArgs e)
{
try
{
//建立FileStream類型引用fs,並傳遞fn作路徑參數,檔案模式為開啟檔案
FileStream fs = new FileStream(fn, FileMode.Open);
//建立BinaryFormatter類對象Fmt
IFormatter Fmt = new BinaryFormatter();
//調用Fmt對象Deserialize方法,傳遞fs
//將fs流中的對象轉換為Details類型,並將引用賦值給Dt
Details Dt = (Details)Fmt.Deserialize(fs);
//將Dt屬性值賦值給以下兩個控制項的Text屬性值
nametxtnew.Text = Dt.Name;
nicknametxtnew.Text = Dt.NickName;
}
//捕捉並顯示檔案未找到異常
catch (FileNotFoundException ex)
{
string str = String.Format("異常資訊:{0}", ex.Message);
MessageBox.Show(str);
}
}       
}
[Serializable]
//定義Details類,實現ISerializable介面
public class Details : ISerializable
{
string _name;
string _nickname;       
//定義兩個公用屬性,可以讀寫相應的私人欄位
public string Name
{
get
{
return _name;
}
set
{
_name = value;
}
}
public string NickName
{
get
{
return _nickname;
}
set
{
_nickname = value;
}
}
public Details() { }
//重載建構函式,接收兩個參數
private Details(SerializationInfo inputinfo, StreamingContext sc)
{
int i;
//擷取"Person Name"名稱的值賦值給_name欄位
_name = inputinfo.GetString("Person Name");
//擷取_name欄位內容中'>'字元索引值加1的整數值
i = _name.IndexOf('>') + 1;
//截取索引i開始的字串內容,並賦值給_name欄位
_name = _name.Substring(i);
//擷取"Person Name"名稱的值賦值給_name欄位
_nickname = inputinfo.GetString("Person NickName");
//擷取_name欄位內容中'>'字元索引值加1的整數值
i = _nickname.IndexOf('>') + 1;
//截取索引i開始的字串內容,並賦值給_nickname欄位
_nickname = _nickname.Substring(i);
}
//實現ISerializable介面的GetObjectData方法,接收兩個參數
void ISerializable.GetObjectData(SerializationInfo outputinfo, StreamingContext sc)
{
//修改所需序列化的欄位值,並修改名稱,填充到outputinfo對象
outputinfo.AddValue("Person Name", "The boy's name is -->" + _name);
outputinfo.AddValue("Person NickName", "The boy's nickname is -->" + _nickname);
}
}
}

程式運行後,除了Text屬性為"檔案路徑"的容器(GroupBox容器控制項)中的控制項外,表單大部分控制項為不可用狀態。輸入檔案名稱到該容器的文字框控制項中(即路徑為程式集目前的目錄),結果7.54所示。

單擊"確定路徑"按鈕後,表單中其他控制項均為可用狀態,而Text屬性為"檔案路徑"的容器中的控制項變為不可用狀態。接著在Text屬性為"原始對象資料"的容器中的文字框控制項中,輸入2個字串值,並單擊"序列化"按鈕,結果7.55所示。

(點擊查看大圖)圖7.54 輸入檔案路徑
(點擊查看大圖)圖7.55 完成序列化

首先程式建立Details類的對象,並根據輸入值對該對象進行了初始化操作。然後將該對象進行序列化操作,自動調用Details類中實現的 GetObjectData()方法,修改欄位值,並指定了相應的索引值。在程式集所在的目錄下已經建立了BoyName.dat檔案,在Visual Studio 2005/Visual Studio 2008中開啟"BoyName.dat"檔案,7.56所示。

(點擊查看大圖)圖7.56 "BoyName.dat"檔案內容

從圖7.56中可看出,首先原始對象的欄位資料進行成功的修改,_name欄位值前面加上了"The boy's name is",_nickname欄位值前面加上"The boy's nickname is"。其次,欄位的名稱沒有被持久化到dat檔案中,其對應索引值分別被修改為"Person Name"和"Person NickName"。最後,單擊"還原序列化"按鈕,結果7.57所示。

(點擊查看大圖)圖7.57 完成還原序列化並輸出

建立Details類的新對象,其欄位資料和原始對象一致,這說明其重載建構函式的操作成功。Details類的重載建構函式序列化時修改的部分進行了逆向操作,還原了原始對象的資料。

解析

一般情況下,序列化的過程細節並不需要考慮,但是在開發程式時要對序列化的過程進行微操作,可以使用自訂序列化完成。常用的自訂序列化方法在定義可序列化的類型時,使之實現using System.Runtime.Serialization..ISerializable介面,當實現該介面後,序列化該類對象的過程將自動調用該類實現的GetObjectData()方法,開發人員所需的微操作可以定義在這個GetObjectData()方法中。相應地,在還原序列化的過程中也可以對過程進行幹預,還原序列化是根據持久化的資料資訊重新建立該類的對象。實現ISerializable介面的類將使用重載的建構函式建立新對象,可以將幹預還原序列化過程的代碼編寫在該類重載建構函式中,如以下代碼所示:

public class Details : ISerializable
{
public Details() { }
//重載建構函式,接收兩個指定類型的參數
private Details(SerializationInfo inputinfo, StreamingContext sc)
{
幹預還原序列化過程的微作業碼;
}
//實現ISerializable介面的GetObjectData方法,接收2個參數
void ISerializable.GetObjectData(SerializationInfo outputinfo, StreamingContext sc)
{
//修改所需序列化的欄位值,並填充到outputinfo對象
outputinfo.AddValue("鍵名", 對序列化欄位的修改值);
}
}

以上代碼中,重載建構函式必須接收指定類型的參數,而實現介面的GetObjectData()方法,調用outputinfo參數的AddValue()方法,即可對序列化過程的資料進行微操作。這個AddValue()方法有多個重載版本,這裡用於修改欄位值。

聯繫我們

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