如何使用BinaryReader和BinaryWriter创建自己的二进制序列化程序?

时间:2011-02-26 16:43:25

标签: c# .net

我基本上想要创建自己的二进制序列化类,有点BinaryFormatter类正在做什么。如何使用BinaryReaderBinaryWriter类来完成此任务。 我不想要任何代码,只需要一个想法。 谢谢。 PS:请不要告诉我使用BinaryFormatter

3 个答案:

答案 0 :(得分:3)

最终,您需要为每种类型选择一种策略,然后切换到每种策略; BinaryWriter有编写Int32,String等的方法 - 所以一个基本的方法是使用大量的反射和一个关于FieldInfo / PropertyInfo的有效类型的GetTypeCode的开关。

就个人而言,实际上,我实际上避免使用 BinaryReader / Writer - 然后直接进入Stream(使用浮动byte []缓冲区进行工作)。

通过使用元编程来预先编译每个成员或每个类型的内容,可以减少反射量。

需要考虑的其他事项:

  • 您需要哪些标题数据(如果有)来标记每个数据字段
  • 您打算如何打包子对象/继承/列表

当然,两者都很容易解决

答案 1 :(得分:0)

要了解如何实现序列化,您可以查看sharpserializer的c#源代码。可以找到源代码here。该代码也适用于windowsmobile,silverlight。

答案 2 :(得分:0)

我建议使用像ProtoBuf .Net这样的东西,您可以使用类中的属性进行设置,它将处理所有二进制序列化/反序列化。

我最近不得不对此进行补充,以便在通用类中提供更紧凑格式的客户序列化支持。就像Marc提到的那样,只需要处理序列化/反序列化特定类型的代码,然后切换为运行您要编写的特定对象类型的代码。

以下是为了允许在泛型类中对数据进行序列化而采用的方法的基本概要:

MemoryStream stream = new MemoryStream();
BinaryWriter writer = new BinaryWriter(stream);

writer.Write(_size);
for (int i = 0; i < _size; i++)
    _indices[i].AddToStream(writer);

if (_serializeDataToStream == null)
    _serializeDataToStream = (Action<BinaryWriter, int, T[]>)GetTypeSpecificSerializationMethod();

_serializeDataToStream(writer, _size, _data);

return stream.ToArray();

这是在泛型类中,_serializeDataToStream是静态的,因此每个泛型类型只需要查找一次

private Delegate GetTypeSpecificSerializationMethod()
{
    if (typeof(T) == typeof(double))
    {
        MethodInfo method = this.GetType().GetMethod("SerializeDouble", BindingFlags.Static | BindingFlags.NonPublic);
        return Delegate.CreateDelegate(typeof(Action<BinaryWriter, int, T[]>), method);
    }
    else if (typeof(T) == typeof(ushort))
    {
    ...


private static void SerializeDouble(BinaryWriter writer, int size, double[] data)
{
    for (int i = 0; i < size; i++)
    {
        writer.Write(data[i]);
    }
}