Protobuf-net:使用 Stream 数据成员序列化第 3 方类 [英] Protobuf-net: Serializing a 3rd party class with a Stream data member

查看:54
本文介绍了Protobuf-net:使用 Stream 数据成员序列化第 3 方类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何序列化类的 Stream(或更准确地说是 Stream 派生的)数据成员?

How do you serialize a Stream (or more correctly Stream derived) data member of a class?

假设我们有一个无法归类的 3rd Party 类:

Assuming we have a 3rd Party class that we can't attribute:

public class Fubar
{
    public Fubar() { ... }
    public string Label { get; set; }
    public int DataType { get; set; }
    public Stream Data { get; set; } // Where it's always actually MemoryStream
};

我正在尝试使用 protobuf-net 来序列化该类.解决我提出的异常和各种 SO 问题:

I'm trying to use protobuf-net to serialize the class. Working through the exceptions and various SO questions I've come up with:

RuntimeTypeModel.Default.Add(typeof(Stream), true)
    .AddSubType(1, typeof(MemoryStream));
RuntimeTypeModel.Default.Add(typeof(Fubar), false)
    .Add(1, "Label")
    .Add(2, "DataType")
    .Add(3, "Data");

using (MemoryStream ms = new MemoryStream())
{
    Fubar f1 = new Fubar();
    /* f1 initialized */

    // Serialize f1
    Serializer.SerializeWithLengthPrefix<Message>(ms, f1, PrefixStyle.Base128);

    // Now let's de-serialize
    ms.Position = 0;
    Fubar f2 = Serializer.DeserializeWithLengthPrefix<Fubar>(ms, PrefixStyle.Base128);
}

以上运行没有错误.标签和数据类型在 f2 中是正确的,但数据变量只是一个空流.调试代码我看到内存流大约是 29 个字节(而 f1 中的数据流本身超过 77KiB).

The above runs with no errors. The Label and DataType are correct in f2 but the Data variable is just an empty stream. Debugging the code I see that the memory stream is something like 29 bytes (while the Data stream in f1 itself is over 77KiB).

我觉得好像我错过了一些相当微不足道的东西,但似乎无法弄清楚它会是什么.我认为确实可以序列化流数据成员.我是否也必须以某种方式为 Stream 或 MemoryStream 类型指定数据属性?

I feel as if I'm missing something fairly trivial but just can't seem to figure out what it would be. I assume that it is indeed possible to serialize a stream data member. Do I have to perhaps somehow specify the data properties for the Stream or MemoryStream types as well?

推荐答案

Stream 是一个非常复杂的野兽,并且没有内置的序列化机制.您的代码将其配置为一种没有有趣成员的类型,这就是它返回为空的原因.

Stream is a very complex beast, and there is no inbuilt serialization mechanism for that. Your code configures it as though it were a type with no interesting members, which is why it is coming back as empty.

对于这种情况,我可能会创建一个代理,并仅使用以下内容进行设置:

For this scenario, I'd probably create a surrogate, and set it up with just:

RuntimeTypeModel.Default.Add(typeof(Fubar), false)
       .SetSurrogate(typeof(FubarSurrogate));

哪里:

[ProtoContract]
public class FubarSurrogate
{
    [ProtoMember(1)]
    public string Label { get; set; }
    [ProtoMember(2)]
    public int DataType { get; set; }
    [ProtoMember(3)]
    public byte[] Data { get; set; }

    public static explicit operator Fubar(FubarSurrogate value)
    {
        if(value == null) return null;
        return new Fubar {
            Label = value.Label,
            DataType = value.DataType,
            Data = value.Data == null ? null : new MemoryStream(value.Data)
        };
    }
    public static explicit operator FubarSurrogate(Fubar value)
    {
        if (value == null) return null;
        return new FubarSurrogate
        {
            Label = value.Label,
            DataType = value.DataType,
            Data = value.Data == null ?
                 null : ((MemoryStream)value.Data).ToArray()
        };
    }
}

这篇关于Protobuf-net:使用 Stream 数据成员序列化第 3 方类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆