如何将对象序列化为字节数组(可移植类库)

时间:2015-03-30 16:56:08

标签: c# serialization portable-class-library

我有一个对象,我想序列化为byte[]以保存或移动它。让我们假设它:

public class Message
{
    public MessageType MessageType { get; set; }

    public byte[] Body { get; set; }
}

public enum MessageType : byte
{
    Type1 = 1,
    Type2 = 2,
}

我的代码是.Net 4.5,Windows 8.1和Windows Phone 8.1 PCL(可移植类库),我遇到的所有库,示例和答案都不能与PCL一起使用,主要是因为它们的使用BinaryFormatter的{​​,在PCL中不可用。

那么,怎么去呢?

1 个答案:

答案 0 :(得分:2)

使用BinaryWriterBinaryReader(两者在PCL项目中都可用),使用简单的类编写自己的序列化程序

public class Message
{
    public MessageType MessageType { get; set; }

    public byte[] Body { get; set; }

    public byte[] Serialize()
    {
        //Data will be serialized in the format 
        //  - MessageType (1 byte)
        //  - BodyLength (4 bytes)
        //  - Body (x Bytes)

        //We allocate a fixed buffer as we know the size already.
        var buffer = new byte[Body.Length + 5];

        using(var ms = new MemoryStream(buffer)
        {
            Serialize(ms);
        }

        //Return our buffer.
        return buffer 
    }

    //Just in case you have a stream instead of a byte[]
    public void Serialize(Stream stream)
    {
        using(var writer = new BinaryWriter(stream, Encoding.UTF8, true))
        {
            writer.Write((byte)this.MessageType);
            writer.Write(Body.Length);
            writer.Write(Body);
        }
    }

    public static Message Deserialize(byte[] data)
    {
        using(var ms = new MemoryStream(data))
        {
            return Message.Deserialize(ms);
        }
    }

    //Just in case you have a stream instead of a byte[]
    public static Message Deserialize(Stream data)
    {
        var message = new Message();

        //Use the default text encoding (does not matter for us) and leave the stream open.
        using(var reader = new BinaryReader(data, Encoding.UTF8, true))
        {
            //We do the same order of operations.
            message.MessageType = (MessageType)reader.ReadByte();
            var bodyLength = reader.ReadInt32();
            message.Body = reader.ReadBytes(bodyLength);
        }

        return message;
    }
}

如果您永远不会使用Streams进行反序列化,那么这是一个简化版本。

    public byte[] Serialize()
    {
        //Data will be serialized in the format 
        //  - MessageType (1 byte)
        //  - Body (x Bytes)

        //We allocate a fixed buffer as we know the size already.
        var data = new byte[Body.Length + 1];

        data[0] = (byte)this.MessageType;
        //We copy the data from Body in to data starting at index 1 in data.
        Array.Copy(Body, 0, data, 1, Body.Length);    

        return data;
    }

    public static Message Deserialize(byte[] data)
    {
        var message = new Message();

        //We do the same order of operations.
        message.MessageType = (MessageType)data[0];

        //Create a new array and copy the body data in to it.
        var body = new byte[data.Length - 1];
        Array.Copy(data, 1, body, 0, data.Length - 1);

        //Assign the body array to the property.
        message.Body = body;

        return message;
    }
}