C# 自定義序列化數據

來源:互聯網
上載者:User

由於使用默認的序列化數據,是使用反射技術來進行的。因此速度有點問題。為了,是速度提高,可以

採用自定義序列化。要實現自定義序列化,需實現ISerializable介面。

代碼如下:

View Code

    [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);        }    }

1.需要實現這個介面。

這個介面方法,是實現了要序列化哪些數據。

2.需要一個構造函數,構造函數是這樣的。

     protected MyObject(SerializationInfo info, StreamingContext context)        {            n1 = info.GetInt32("i");            n2 = info.GetInt32("j");            str = info.GetString("k");        }

這個構造函數,是在類被還原序列化的時候調用,在這裡可以指定要還原序列化的內容。

3.調用的時候,和正常序列化一樣。

4.對應有繼承的類,實現序列化的時候,也要實現一個介面,一個構造函數。在這2個方法中

要調用基類的方法。代碼如下:

View Code

    [Serializable]    public class ObjectTwo : MyObject, IDeserializationCallback     {        public int num;        public ObjectTwo()            : base()        {        }        protected ObjectTwo(SerializationInfo si, StreamingContext context)            : base(si, context)        {            num = si.GetInt32("num");        }        [SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter        = true)]        public override void GetObjectData(SerializationInfo si, StreamingContext context)        {            base.GetObjectData(si, context);            si.AddValue("num", num);        }        #region IDeserializationCallback 成員        public void OnDeserialization(object sender)        {            num = n1 + n2;        }        #endregion    }

注意:在GetObjectData方法上,最好加一個安全屬性

   [SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter
        = true)]。

  [System.Xml.Serialization.XmlElementAttribute(Order=0)] 屬性加在屬性上,可以設置

序列化的順序。

5.為了能在反序列數據後,能執行一定的操作,需要給該類,繼承IDeserializationCallback介面

這樣,在完成還原序列化數據後,能執行一個操作。這裡是在還原序列化完成後,調用基類的數據,產生數據相加。

        #region IDeserializationCallback 成員        public void OnDeserialization(object sender)        {            num = n1 + n2;        }        #endregion

6.在儲存序列化,反序列數據可以用繼承Stream的任何類。如:FileStream檔案流。MemoryStream內存流。

7.在產生序列化,還原序列化,可以指定是二進制,或則sop等。如:SoapFormatter BinaryFormatter。序列化和

還原序列化數據,要用相同的格式。

8.對應不想序列化的屬性,只需要加[NonSerialized]這個就可以了,那麼該屬性在序列化的時候,不會被序列化。

9.大數據序列化

9.1定義服務器端的返回數據

    [XmlType(Namespace = "http://my.namespace.com/data")]    public class Content    {        [XmlElement]        public string name;        [XmlElement]        public string extension;        [XmlElement]        public byte[] data;    }

其中byte[] 就是放大數據的。

9.2客戶端接受的實體,需要繼承IXmlSerializable介面

代碼如下:

View Code

public partial class Content : IXmlSerializable{    private Stream stream;    private string streamFileName;    public Stream DataStream    {        set { this.stream = value; }    }    public Stream GetDataStream()    {        return File.OpenRead(this.streamFileName);    }    public XmlSchema GetSchema()    {        return null;    }    public void ReadXml(XmlReader reader)    {        reader.ReadStartElement(); //wrapping element        this.name = reader.ReadElementContentAsString();        this.extension = reader.ReadElementContentAsString();        string tempFileName = Path.GetTempFileName();        this.streamFileName = tempFileName;        using (FileStream fs = File.Create(tempFileName))        {            byte[] buffer = new byte[1000];            int bytesRead;            reader.ReadStartElement();            do            {                bytesRead = reader.ReadContentAsBase64(buffer, 0, buffer.Length);                fs.Write(buffer, 0, bytesRead);            } while (bytesRead > 0);            reader.ReadEndElement();        }        reader.ReadEndElement(); //wrapping element    }    public void WriteXml(XmlWriter writer)    {        writer.WriteStartElement("name");        writer.WriteValue(this.name);        writer.WriteEndElement();        writer.WriteStartElement("extension");        writer.WriteValue(this.extension);        writer.WriteEndElement();        writer.WriteStartElement("data");        XmlDictionaryWriter dictWriter = writer as XmlDictionaryWriter;        bool isMtom = dictWriter != null && dictWriter is IXmlMtomWriterInitializer;        if (isMtom)        {            dictWriter.WriteValue(new MyStreamProvider(this.stream));        }        else        {            // fall back to the original behavior            byte[] buffer = new byte[1000];            int bytesRead;            do            {                bytesRead = this.stream.Read(buffer, 0, buffer.Length);                if (bytesRead > 0)                {                    writer.WriteBase64(buffer, 0, bytesRead);                }            } while (bytesRead > 0);        }        writer.WriteEndElement();    }    class MyStreamProvider : IStreamProvider    {        Stream stream;        public MyStreamProvider(Stream stream)        {            this.stream = stream;        }        public Stream GetStream()        {            return this.stream;        }        public void ReleaseStream(Stream stream)        {        }    }}

9.3客戶端調用代碼如下:

View Code

            SomeServiceClient c = new SomeServiceClient();            byte[] fileContents = new byte[100];            for (int i = 0; i < fileContents.Length; i++)            {                fileContents[i] = (byte)'a';            }            RequestClass request = new RequestClass            {                id = "id",                token = "token",                content = new Content                {                    name = "file",                    extension = "ext",                    //data = fileContents,                    DataStream = new MemoryStream(fileContents),                },            };            c.SendRequest(request);            ResponseClass resp = c.GetResponse(234);            Console.WriteLine(resp.content.name);            Stream dataStream = resp.content.GetDataStream();            string text = new StreamReader(dataStream).ReadToEnd();

 

 

 

 

 

相關文章

聯繫我們

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