C#編程總結(一)序列化

C#編程總結(一)序列化

 序列化是將對象狀態轉換爲可保持或傳輸的格式的過程。與序列化相對的是反序列化,它將流轉換爲對象。這兩個過程結合起來,能夠輕鬆地存儲和傳輸數據。編程

幾種序列化技術:
      1)二進制序列化保持類型保真度,這對於在應用程序的不一樣調用之間保留對象的狀態頗有用。例如,經過將對象序列化到剪貼板,可在不一樣的應用程序之間共享對象。您能夠將對象序列化到流、磁盤、內存和網絡等等。遠程處理使用序列化「經過值」在計算機或應用程序域之間傳遞對象。
      2)XML 序列化僅序列化公共屬性和字段,且不保持類型保真度。當您要提供或使用數據而不限制使用該數據的應用程序時,這一點是頗有用的。因爲 XML 是一個開放式標準,所以,對於經過 Web 共享數據而言,這是一個很好的選擇。SOAP 一樣是一個開放式標準,這使它也成爲一個頗具吸引力的選擇。json

     3)使用提供的數據協定,將類型實例序列化和反序列化爲 XML 流或文檔(或者JSON格式)。常應用於WCF通訊。數組

BinaryFormatter

序列化可被定義爲將對象的狀態存儲到存儲媒介中的過程。在此過程當中,對象的公共字段和私有字段以及類的名稱(包括包含該類的程序集)都被轉換爲字節流,而後寫入數據流。在之後反序列化該對象時,建立原始對象的精確複本。安全

一、使一個類可序列化的最簡單方式是按以下所示使用 Serializable 屬性標記。網絡

二、有選擇的序列化app

     經過用 NonSerialized 屬性標記成員變量,能夠防止它們被序列化ide

三、自定義序列化函數

     1) 在序列化期間和以後運行自定義方法
最佳作法也是最簡單的方法(在 .Net Framework 2.0 版中引入),就是在序列化期間和以後將下列屬性應用於用於更正數據的方法:
OnDeserializedAttribute
OnDeserializingAttribute
OnSerializedAttribute
OnSerializingAttribute性能

具體事例以下:this

// 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.";
    }    
}
View Code

      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);
  }
}
View Code

注意:

在反序列化一個對象時不調用構造函數。出於性能方面的緣由對反序列化施加了該約束。可是,這違反了運行庫與對象編寫器之間的一些一般約定,開發人員應確保他們在將對象標記爲可序列化時瞭解其後果。

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的輸出

一、默認值

DefaultValueAttribute 

二、過濾某屬性或字段

 XmlIgnoreAttribute

三、重寫默認序列化邏輯

具體可見: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

四、將對象序列化爲 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));
        }
    }
View Code

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
    }
}

具體的實例代碼以下:

 下載

相關文章
相關標籤/搜索