分享

ISerializable接口简析

 长江黄鹤 2018-05-14

ISerializable接口的定义如下:

namespace System.Runtime.Serialization 

    // Summary: 
    //     Allows an object to control its own serialization and deserialization. 
    [ComVisible(true)] 
    public interface ISerializable 
    { 
        // Summary: 
        //     Populates a System.Runtime.Serialization.SerializationInfo with the data 
        //     needed to serialize the target object. 
        // 
        // Parameters: 
        //   info: 
        //     The System.Runtime.Serialization.SerializationInfo to populate with data. 
        // 
        //   context: 
        //     The destination (see System.Runtime.Serialization.StreamingContext) for this 
        //     serialization. 
        // 
        // Exceptions: 
        //   System.Security.SecurityException: 
        //     The caller does not have the required permission. 
        void GetObjectData(SerializationInfo info, StreamingContext context); 
    } 
}

其中只有一个函数GetObjectData。

定义一个实现了ISerializable接口的Class,作为测试用,我在其中定义了一个Dictionary数组和一个Byte[]。并重载GetObjectData,将这两个Field在Serialize的过程中存储起来。

[Serializable
internal class TestData : ISerializable 

    internal Dictionary dictTest = new Dictionary(); 
    internal Byte[] byData = null;

    internal TestData() 
    { 
    }

    protected TestData(SerializationInfo info, StreamingContext context) 
    { 
        dictTest = (Dictionary)info.GetValue("Dict", typeof(Dictionary)); 
        byData = (Byte[])info.GetValue("Byte", typeof(Byte[])); 
    }

    #region ISerializable Members 
    [SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)] 
    public void GetObjectData(SerializationInfo info, StreamingContext context) 
    { 
        if (info == null) 
            throw new NullReferenceException("info is null!");

        info.AddValue("Dict", dictTest); 
        info.AddValue("Byte", byData); 
    } 
    #endregion 
}

测试一下该对象,可以将对象存在Byte[]中或者char[]中。

static void Main(string[] args) 

    Console.WriteLine("Initialize the test data.."); 
    TestData td = new TestData(); 
    td.dictTest.Add(1, "TEST 1"); 
    td.dictTest.Add(2, "Test 2"); 
    td.byData = new byte[3]; 
    td.byData[0] = 1; 
    td.byData[1] = 9; 
    td.byData[2] = 5;

    int count; 
    byte[] byteArray; 
    char[] charArray; 
    UnicodeEncoding uniEncoding = new UnicodeEncoding(); 
    using (MemoryStream memStream = new MemoryStream(100)) 
    { 
        BinaryFormatter binaryFmt = new BinaryFormatter(); 
        binaryFmt.Serialize(memStream, td);

        // Write the stream properties to the console. 
        Console.WriteLine( 
            "Capacity = {0}, Length = {1}, Position = {2}/n", 
            memStream.Capacity.ToString(), 
            memStream.Length.ToString(), 
            memStream.Position.ToString());

        // Set the position to the beginning of the stream. 
        memStream.Seek(0, SeekOrigin.Begin);

        // Read the first 20 bytes from the stream. 
        byteArray = new byte[memStream.Length]; 
        count = memStream.Read(byteArray, 0, memStream.Length);

        // Read the remaining bytes, byte by byte. 
        while (count < memStream.Length) 
        { 
            byteArray[count++] = 
                Convert.ToByte(memStream.ReadByte()); 
        }

        // Decode the byte array into a char array 
        // and write it to the console. 
        charArray = new char[uniEncoding.GetCharCount( 
            byteArray, 0, count)]; 
        uniEncoding.GetDecoder().GetChars( 
            byteArray, 0, count, charArray, 0); 
        Console.WriteLine(charArray);

       // Afterwards, deserialization 
        Console.WriteLine("Deserialzie..."); 
        binaryFmt = new BinaryFormatter(); 
        memStream.Seek(0, SeekOrigin.Begin); 
        TestData td2 = (TestData)binaryFmt.Deserialize(memStream); 
        Console.WriteLine(td2.byData); 
        Console.WriteLine(td2.dictTest.Count); 
    }           

    Console.ReadLine(); 
}

这段测试代码中,使用MemoryStream来保存Serialze的数据,并使用BinaryFormatter来说明该Memory的表现格式。为了测试,使用UnicodeEncoding来对该内存块中的Byte[]进行解码,当然,其后的Console.WriteLine对其进行输出,通常是一堆乱码文字。

其后,该段代码还对同一块MemoryStream进行了Deseralize的测试。这在实际处理中并不存在,通常MemoryStream的内容会被导入文件或者数据库等存储位置。并简单的输出了Deserialization后的结果。通过设置Breaking Point可以得到更详细的内容。

还有一种没有被上述代码所提及的方法,那就是使用BitConverter类。如:

BitConverter.ToString( bytes );

就可以非常简单的把byte[]转化为String,可以很方便的进行存储。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多