首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Protobuf-net:使用流数据成员序列化第三方类

Protobuf-net:使用流数据成员序列化第三方类
EN

Stack Overflow用户
提问于 2013-06-27 02:00:57
回答 2查看 465关注 0票数 2

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

假设我们有一个不能归属的第三方类:

代码语言:javascript
运行
复制
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问题:

代码语言:javascript
运行
复制
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中的标签和DataType是正确的,但数据变量只是一个空流。调试代码时,我看到内存流大约是29字节(而f1中的数据流超过77KiB)。

我觉得我好像错过了一些相当微不足道的东西,但似乎就是想不出它会是什么。我假设确实可以序列化一个流数据成员。我是否还需要以某种方式指定Stream或MemoryStream类型的数据属性?

EN

Stack Overflow用户

回答已采纳

发布于 2013-06-27 04:53:44

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

对于这个场景,我可能会创建一个代理,并使用以下命令设置它:

代码语言:javascript
运行
复制
RuntimeTypeModel.Default.Add(typeof(Fubar), false)
       .SetSurrogate(typeof(FubarSurrogate));

其中:

代码语言:javascript
运行
复制
[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()
        };
    }
}
票数 3
EN
查看全部 2 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17327277

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档