【问题标题】:Google Protocol Buffers - protobuf-net deserialization not working properlyGoogle 协议缓冲区 - protobuf-net 反序列化无法正常工作
【发布时间】:2023-03-23 20:11:01
【问题描述】:

我在成功反序列化已使用预编译的 protobuff 序列化程序类 ModelSerializer 序列化的字节数组时遇到了困难。使用它,我定义的数据模型MyData 中的类的序列化和反序列化在我序列化到文件并从文件反序列化到MyData 时起作用。

不过,我还有一个需求,就是将MyData序列化为字节数组,将字节数组反序列化为MyData。下面是名为MyDataConverter 的基本类,它有两个静态方法,一个将MyData 转换为字节数组,另一个将字节数组转换为MyData

我可以成功地将MyData 序列化为字节数组并将其写入MemoryStream。但是,当我反序列化字节数组时,我确实得到了MyData 的非空实例,但其中的所有数据都丢失了(默认为零,或自定义类型的null 值)。

我会在这里出错吗?请注意,我确实使用了类似的代码来成功序列化到文件并从文件反序列化,因此 MyModel 和预编译的 ModelSerializer 可能都没有问题。但如有必要,我可以在此处粘贴一些信息。

public class MyDataConverter
{
    public static byte [] MyDataToBytes (MyData myData)
    {
        MemoryStream stream = new MemoryStream();
        ModelSerializer serializer = new ModelSerializer();

        serializer.Serialize (stream, myData);
        byte [] bytes = stream.ToArray();
        Stream.Close();

        return bytes;
    }

    public static MyData BytesToMyData (byte [] bytes)
    {
        MyData myData = null;

        MemoryStream stream = new MemoryStream();
        stream.Write (bytes, 0, bytes.Length);

        ModelSerializer serializer = new ModelSerializer();

        myData = (MyData) serializer.Deserialize (stream, myData, typeof (MyData));
        stream.Close();

        return myData;
    }
}

【问题讨论】:

    标签: c# serialization protobuf-net protocol-buffers


    【解决方案1】:

    这就是问题所在:

    MemoryStream stream = new MemoryStream();
    stream.Write (bytes, 0, bytes.Length);
    
    ModelSerializer serializer = new ModelSerializer();
    myData = (MyData) serializer.Deserialize (stream, myData, typeof (MyData));
    

    当您尝试反序列化时,您仍处于流的end。之后你可以从头开始,但更改代码以将字节数组传递给构造函数会更简单:

    MemoryStream stream = new MemoryStream(bytes, false);        
    ModelSerializer serializer = new ModelSerializer();
    myData = (MyData) serializer.Deserialize (stream, myData, typeof (MyData));
    

    【讨论】:

    • 非常感谢!完美运行。只是为了提高我的理解,是因为在使用 stream.Write 将字节数组写入流之后,流位置在末尾,因此当我将流传递给反序列化器时,它是不正确的?而用字节数组构造一个新的内存流不会改变流的位置(或者构造函数已经帮助将它移回)。我的理解正确吗?
    • 是的,就是这样 - 构造函数为其提供数据,但“光标”仍位于流的开头。 (另外,使用这种形式,您不会得到另一个数据副本 - 流基本上只是原始字节数组的视图。)
    • 太棒了.. 非常感谢您如此快速简洁的回复!
    • 如果我们每次都能得到一分钱,那就是:“你还没有倒带”,“不要使用GetBuffer(),除非你跟踪.Length”,或者"不要使用Encoding 将非文本二进制文件转换为string"...
    • @MarcGravell:确实——前几天我开始写一篇关于“编码可以咬你的方式”的博客文章,但由于需要太多介绍而中止了它。也许有一天……
    【解决方案2】:

    我们可以将像 List 这样的对象列表作为输入传递给序列化器吗?

    【讨论】:

    • 最好是发表评论。
    • 目前,我们正在开发一个使用 C#、.NET 和 highchart 技术显示汽车相关数据的 highcharts 的 web 应用程序。我们可以为 Web 应用程序使用 Protobuf-net 序列化和反序列化方法吗?我们需要 JSON 序列化字符串,其中包含作为 highcharts 输入提供的报告对象数据。报表对象是对象 ReportViewModel 的列表,其中包含许多数据列表。考虑到这种情况,我们能否将 ProtoBuf-net 用于我们的 Web 应用程序。
    • MemoryStream 流 = new MemoryStream();序列化器.序列化(流,报告);
    • 我正在尝试如上所述进行序列化,但它似乎工作正常。此流未包含所有报告数据!!!
    猜你喜欢
    • 1970-01-01
    • 2017-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多