序列化是將對象狀態轉換為可保持或傳輸的格式的過程。與序列化相對的是還原序列化,它將流轉換為對象。這兩個過程結合起來,可以輕鬆地儲存和傳輸資料。
幾種序列化技術:
1)二進位序列化保持類型逼真度,這對於在應用程式的不同調用之間保留對象的狀態很有用。例如,通過將對象序列化到剪貼簿,可在不同的應用程式之間共用對象。您可以將對象序列化到流、磁碟、記憶體和網路等等。遠端使用序列化“通過值”在電腦或應用程式定義域之間傳遞對象。
2)XML 序列化僅序列化公用屬性和欄位,且不保持類型逼真度。當您要提供或使用資料而不限制使用該資料的應用程式時,這一點是很有用的。由於 XML 是一個開放式標準,因此,對於通過 Web 共用資料而言,這是一個很好的選擇。SOAP 同樣是一個開放式標準,這使它也成為一個頗具吸引力的選擇。
3)使用提供的資料合約,將類型執行個體序列化和還原序列化為 XML 流或文檔(或者JSON格式)。常應用於WCF通訊。
BinaryFormatter
序列化可被定義為將對象的狀態儲存到儲存媒介中的過程。在此過程中,對象的公用欄位和私人欄位以及類的名稱(包括包含該類的程式集)都被轉換為位元組流,然後寫入資料流。在以後還原序列化該對象時,建立原始對象的精確複本。
1、使一個類可序列化的最簡單方式是按如下所示使用 Serializable 屬性標記。
2、有選擇的序列化
通過用 NonSerialized 屬性標記成員變數,可以防止它們被序列化
3、自訂序列化
1) 在序列化期間和之後運行自訂方法
最佳做法也是最簡單的方法(在 .Net Framework 2.0 版中引入),就是在序列化期間和之後將下列屬性應用於用於更正資料的方法:
- OnDeserializedAttribute
- OnDeserializingAttribute
- OnSerializedAttribute
- OnSerializingAttribute
具體案例如下:
// This is the object that will be serialized and deserialized.[Serializable()] public class TestSimpleObject { // This member is serialized and deserialized with no change. public int member1; // The value of this field is set and reset during and // after serialization. private string member2; // This field is not serialized. The OnDeserializedAttribute // is used to set the member value after serialization. [NonSerialized()] public string member3; // This field is set to null, but populated after deserialization. private string member4; // Constructor for the class. public TestSimpleObject() { member1 = 11; member2 = "Hello World!"; member3 = "This is a nonserialized value"; member4 = null; } public void Print() { Console.WriteLine("member1 = '{0}'", member1); Console.WriteLine("member2 = '{0}'", member2); Console.WriteLine("member3 = '{0}'", member3); Console.WriteLine("member4 = '{0}'", member4); } [OnSerializing()] internal void OnSerializingMethod(StreamingContext context) { member2 = "This value went into the data file during serialization."; } [OnSerialized()] internal void OnSerializedMethod(StreamingContext context) { member2 = "This value was reset after serialization."; } [OnDeserializing()] internal void OnDeserializingMethod(StreamingContext context) { member3 = "This value was set during deserialization"; } [OnDeserialized()] internal void OnDeserializedMethod(StreamingContext context) { member4 = "This value was set after deserialization."; } }
2) 實現 ISerializable 介面
對於用 Serializable 屬性標記且在類層級上或其建構函式上具有聲明性或命令性安全的類,不應使用預設序列化。相反,這些類應始終實現 ISerializable 介面。實現 ISerializable 涉及實現 GetObjectData 方法以及在還原序列化對象時使用的特殊建構函式。
具體執行個體如下:
[Serializable]public class MyObject : ISerializable { public int n1; public int n2; public String str; public MyObject() { } protected MyObject(SerializationInfo info, StreamingContext context) { n1 = info.GetInt32("i"); n2 = info.GetInt32("j"); str = info.GetString("k"); }[SecurityPermissionAttribute(SecurityAction.Demand,SerializationFormatter =true)] public virtual void GetObjectData(SerializationInfo info, StreamingContext context) { info.AddValue("i", n1); info.AddValue("j", n2); info.AddValue("k", str); }}
注意:
在還原序列化一個對象時不調用建構函式。出於效能方面的原因對還原序列化施加了該約束。但是,這違反了運行庫與對象編寫器之間的一些通常約定,開發人員應確保他們在將對象標記為可序列化時瞭解其後果。
SoapFormatter
以 SOAP 格式將對象或整個連線物件的圖形序列化和還原序列化。基本用法類似於BinaryFormatter。SoapFormatter 和 BinaryFormatter 兩個類實現 IRemotingFormatter 介面以支援遠端程序呼叫 (RPC),實現 IFormatter 介面(由 IRemotingFormatter 繼承)以支援對象圖形的序列化。SoapFormatter 類還支援對 ISoapMessage 對象進行 RPC,而不必使用 IRemotingFormatter 功能。
XmlSerializer
將對象序列化到 XML 文檔中和從 XML 文檔中還原序列化對象。XmlSerializer 使您得以控制如何將對象編碼到 XML 中。
XML 序列化是將對象的公用屬性 (Property) 和欄位轉換為序列格式(這裡是指 XML)以便儲存或傳輸的過程。還原序列化則是從 XML 輸出中重新建立原始狀態的對象。因此,可以將序列化視為將對象的狀態儲存到流或緩衝區的方法。例如,ASP.NET 使用 XmlSerializer 類對 XML Web services 訊息進行編碼。
例子:
C#代碼
public class MyClass{ public MyObject MyObjectProperty;}public class MyObject{ public string ObjectName;}
序列化後的XML
<MyClass> <MyObjectProperty> <ObjectName>My String</ObjectName> </MyObjectProperty></MyClass>
還可以通過標記來控制XML的輸出
1、預設值
DefaultValueAttribute
2、過濾某屬性或欄位
XmlIgnoreAttribute
3、重寫預設序列化邏輯
具體可見:http://msdn.microsoft.com/zh-cn/library/system.xml.serialization.xmlattributeoverrides(v=vs.80).aspx
其他控制手段,具體可見http://msdn.microsoft.com/zh-cn/library/83y7df3e(v=vs.80).aspx
4、將對象序列化為 SOAP 編碼的 XML 流
http://msdn.microsoft.com/zh-cn/library/bd04skah(v=vs.80).aspx
注意
XML 序列化不轉換方法、索引器、私人欄位或唯讀屬性(唯讀集合除外)。要序列化對象的所有欄位和屬性(公用的和私人的),請使用 BinaryFormatter,而不要使用 XML 序列化。
DataContractSerializer
使用提供的資料合約,將類型執行個體序列化和還原序列化為 XML 流或文檔。 此類不能被繼承。
DataContractSerializer 用於序列化和還原序列化在 Windows Communication Foundation (WCF) 訊息中發送的資料。 通過將 DataContractAttribute 屬性 (Attribute) 應用於類,而將 DataMemberAttribute 屬性 (Attribute) 應用於類成員,可以指定要序列化的屬性 (Property) 和欄位。
使用步驟:
1)DataContractSerializer 與 DataContractAttribute 和 DataMemberAttribute 類結合使用。
要準備序列化某個類,請將 DataContractAttribute 應用於該類。 對於返回要序列化的資料的類的每個成員,請應用 DataMemberAttribute。 您可以序列化欄位和屬性,而無論其可訪問性層級是什麼:private、protected、internal、protected internal 或 public。
2)添加到已知類型的集合中
在序列化或還原序列化對象時,DataContractSerializer 必須“已知”該類型。 首先,建立一個實現 IEnumerable<T>(如 List<T>)的類執行個體,並將已知類型添加到集合中。 然後,使用接受 IEnumerable<T>(例如,[M:System.Runtime.Serialization.DataContractSerializer.#ctor(System.Type,System.Collections.Generic.IEnumerable{System.Type}])的重載之一建立 DataContractSerializer 的執行個體。
具體執行個體:
namespace DataContractSerializerExample{ using System; using System.Collections; using System.Collections.Generic; using System.Runtime.Serialization; using System.Xml; // You must apply a DataContractAttribute or SerializableAttribute // to a class to have it serialized by the DataContractSerializer. [DataContract(Name = "Customer", Namespace = "http://www.contoso.com")] class Person : IExtensibleDataObject { [DataMember()] public string FirstName; [DataMember] public string LastName; [DataMember()] public int ID; public Person(string newfName, string newLName, int newID) { FirstName = newfName; LastName = newLName; ID = newID; } private ExtensionDataObject extensionData_Value; public ExtensionDataObject ExtensionData { get { return extensionData_Value; } set { extensionData_Value = value; } } } public sealed class Test { private Test() { } public static void Main() { try { WriteObject("DataContractSerializerExample.xml"); ReadObject("DataContractSerializerExample.xml"); } catch (SerializationException serExc) { Console.WriteLine("Serialization Failed"); Console.WriteLine(serExc.Message); } catch (Exception exc) { Console.WriteLine( "The serialization operation failed: {0} StackTrace: {1}", exc.Message, exc.StackTrace); } finally { Console.WriteLine("Press <Enter> to exit...."); Console.ReadLine(); } } public static void WriteObject(string fileName) { Console.WriteLine( "Creating a Person object and serializing it."); Person p1 = new Person("Zighetti", "Barbara", 101); FileStream writer = new FileStream(fileName, FileMode.Create); DataContractSerializer ser = new DataContractSerializer(typeof(Person)); ser.WriteObject(writer, p1); writer.Close(); } public static void ReadObject(string fileName) { Console.WriteLine("Deserializing an instance of the object."); FileStream fs = new FileStream(fileName, FileMode.Open); XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(fs, new XmlDictionaryReaderQuotas()); DataContractSerializer ser = new DataContractSerializer(typeof(Person)); // Deserialize the data and read it from the instance. Person deserializedPerson = (Person)ser.ReadObject(reader, true); reader.Close(); fs.Close(); Console.WriteLine(String.Format("{0} {1}, ID: {2}", deserializedPerson.FirstName, deserializedPerson.LastName, deserializedPerson.ID)); } }
DataContractJsonSerializer
將對象序列化為 JavaScript 物件標記法 (JSON),並將 JSON 資料還原序列化為對象。 此類不能被繼承。
具體使用與DataContractSerializer類似。這裡不再贅述。
下面對這些方法的使用做了匯總,希望能給大家帶來一些協助。
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.IO;using System.Runtime.Serialization;using System.Runtime.Serialization.Json;using System.Runtime.Serialization.Formatters.Binary;using System.Runtime.Serialization.Formatters.Soap;using System.Xml.Serialization;namespace SerializerSample{ /// <summary> /// 序列化協助類 /// </summary> public sealed class SerializeHelper { #region DataContract序列化 /// <summary> /// DataContract序列化 /// </summary> /// <param name="value"></param> /// <param name="knownTypes"></param> /// <returns></returns> public static string SerializeDataContract(object value, List<Type> knownTypes = null) { DataContractSerializer dataContractSerializer = new DataContractSerializer(value.GetType(), knownTypes); using (MemoryStream ms = new MemoryStream()) { dataContractSerializer.WriteObject(ms, value); ms.Seek(0, SeekOrigin.Begin); using (StreamReader sr = new StreamReader(ms)) { return sr.ReadToEnd(); } } } /// <summary> /// DataContract還原序列化 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="xml"></param> /// <returns></returns> public static T DeserializeDataContract<T>(string xml) { using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(xml))) { DataContractSerializer serializer = new DataContractSerializer(typeof(T)); return (T)serializer.ReadObject(ms); } } #endregion #region DataContractJson序列化 /// <summary> /// DataContractJson序列化 /// </summary> /// <param name="value"></param> /// <returns></returns> public static string SerializeDataContractJson(object value) { DataContractJsonSerializer dataContractSerializer = new DataContractJsonSerializer(value.GetType()); using (MemoryStream ms = new MemoryStream()) { dataContractSerializer.WriteObject(ms, value); return Encoding.UTF8.GetString(ms.ToArray()); } } /// <summary> /// DataContractJson還原序列化 /// </summary> /// <param name="type"></param> /// <param name="str"></param> /// <returns></returns> public static object DeserializeDataContractJson(Type type, string str) { DataContractJsonSerializer dataContractSerializer = new DataContractJsonSerializer(type); using (MemoryStream ms = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(str))) { return dataContractSerializer.ReadObject(ms); } } /// <summary> /// DataContractJson還原序列化 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="json"></param> /// <returns></returns> public T DeserializeDataContractJson<T>(string json) { DataContractJsonSerializer dataContractSerializer = new DataContractJsonSerializer(typeof(T)); using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(json))) { return (T)dataContractSerializer.ReadObject(ms); } } #endregion #region XmlSerializer序列化 /// <summary> /// 將對象序列化到 XML 文檔中和從 XML 文檔中還原序列化對象。XmlSerializer 使您得以控制如何將對象編碼到 XML 中。 /// </summary> /// <param name="value"></param> /// <returns></returns> public static string SerializeXml(object value) { XmlSerializer serializer = new XmlSerializer(value.GetType()); using (MemoryStream ms = new MemoryStream()) { serializer.Serialize(ms, value); ms.Seek(0, SeekOrigin.Begin); using (StreamReader sr = new StreamReader(ms)) { return sr.ReadToEnd(); } } } /// <summary> /// XmlSerializer還原序列化 /// </summary> /// <param name="type"></param> /// <param name="str"></param> /// <returns></returns> public static object DeserializeXml(Type type, string str) { XmlSerializer serializer = new XmlSerializer(type); byte[] bytes = System.Text.Encoding.UTF8.GetBytes(str); using (MemoryStream ms = new MemoryStream(bytes)) { return serializer.Deserialize(ms); } } #endregion #region BinaryFormatter序列化 /// <summary> /// BinaryFormatter序列化 /// 必須類型必須標記為Serializable /// </summary> /// <param name="obj"></param> /// <returns></returns> public static string SerializeBinaryFormatter(object obj) { BinaryFormatter formatter = new BinaryFormatter(); using (MemoryStream ms = new MemoryStream()) { formatter.Serialize(ms,obj); byte[] bytes = ms.ToArray(); obj = formatter.Deserialize(new MemoryStream(bytes)); //如果是UTF8格式,則還原序列化報錯。可以用Default格式,不過,建議還是傳參為byte數組比較好 return Encoding.Default.GetString(bytes); } } /// <summary> /// BinaryFormatter還原序列化 /// 必須類型必須標記為Serializable /// </summary> /// <param name="serializedStr"></param> /// <returns></returns> public static T DeserializeBinaryFormatter<T>(string serializedStr) { BinaryFormatter formatter = new BinaryFormatter(); byte[] bytes = Encoding.Default.GetBytes(serializedStr); using (MemoryStream ms = new MemoryStream(bytes)) { return (T)formatter.Deserialize(ms); } } #endregion #region SoapFormatter序列化 /// <summary> /// SoapFormatter序列化 /// 必須類型必須標記為Serializable /// </summary> /// <param name="obj"></param> /// <returns></returns> public static string SerializeSoapFormatter(object obj) { SoapFormatter formatter = new SoapFormatter(); using (MemoryStream ms = new MemoryStream()) { formatter.Serialize(ms, obj); byte[] bytes = ms.ToArray(); return Encoding.UTF8.GetString(bytes); } } /// <summary> /// SoapFormatter還原序列化 /// 必須類型必須標記為Serializable /// </summary> /// <param name="serializedStr"></param> /// <returns></returns> public static T DeserializeSoapFormatter<T>(string serializedStr) { SoapFormatter formatter = new SoapFormatter(); using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(serializedStr))) { return (T)formatter.Deserialize(ms); } } #endregion }}
具體的執行個體代碼如下:
下載:demo
以上就是本文的全部內容,希望對大家的學習有所協助,也希望大家多多支援雲棲社區。