当前位置 : 主页 > 大数据 > 区块链 >

使用protobuf为c#反序列化“long”字符串对我来说无法正常工作

来源:互联网 收集:自由互联 发布时间:2021-06-22
我显然做了一些基本的错误,但我无法弄明白,也找不到文档. 我正在尝试使用Marc Gravell的.NET for proto-buf,并尝试序列化和反序列化对象.一旦一个对象包含一个“太长”的字符串(没有试图确
我显然做了一些基本的错误,但我无法弄明白,也找不到文档.

我正在尝试使用Marc Gravell的.NET for proto-buf,并尝试序列化和反序列化对象.一旦一个对象包含一个“太长”的字符串(没有试图确定大小阈值,但它只有几百个字节),字符串不会为我正确反序列化.

这是我的代码:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using ProtoBuf;

namespace ConsoleApplication1
{
public class Program
{
    [ProtoContract]
    public class test
    {
        [ProtoMember(1)]            
        public int i;
        [ProtoMember(2)]
        public string s1;
        [ProtoMember(3)]
        public string s2;
        [ProtoMember(4)]
        public char[] arrchars;
        [ProtoMember(5)]
        public Dictionary<int, string> Dict = new Dictionary<int, string>();

    }


    static void Main(string[] args)
    {
        test var1 = new test();
        var1.i = 10;
        var1.s1 = "Hello";
        var1.arrchars = new char[] {'A', 'B', 'C'};
        var1.Dict.Add(10, "ten");
        var1.Dict.Add(5, "five");
        var1.s2 = new String('X', 520);

        string s = PBSerializer.Serialize(typeof (test), var1);

        test var2 = null;
        PBSerializer.Deserialize(s, out var2);
    }


    public static class PBSerializer
    {
        public static string Serialize(Type objType, object obj)
        {
            MemoryStream stream = new MemoryStream();
            ProtoBuf.Serializer.Serialize(stream, obj);
            // ProtoBuf.Serializer.SerializeWithLengthPrefix(stream, obj, PrefixStyle.Fixed32, 1);
            stream.Flush();
            stream.Position = 0;
            StreamReader sr = new StreamReader(stream);
            string res = sr.ReadToEnd();
            stream.Dispose();
            sr.Dispose();
            return res;
        }

        public static void Deserialize(string serializedObj, out test obj)
        {
            MemoryStream stream = new MemoryStream(Encoding.ASCII.GetBytes(serializedObj));
            obj = ProtoBuf.Serializer.Deserialize<test>(stream);
            // obj = ProtoBuf.Serializer.DeserializeWithLengthPrefix<test>(stream, PrefixStyle.Fixed32, 1);
            stream.Dispose();
        }

    }

}
}

var2.s2与var1.s2不同 – 它在字符串的开头有一个额外的字符,并截断字符串结尾的大部分.但是,如果我将var1.s2的长度更改为一个较小的数字(比如52而不是520个字符),我的问题就会消失,但我需要能够序列化长字符串.
我假设它与设置PrefixStyle(?)的错误有关,或者我可能没有使用正确的编码(?).但是,反复试验并没有帮助我解决问题.

我正在使用.NET 3.5并尝试使用版本444& 450具有相同的结果.

谢谢.

您正在序列化二进制数据 – 但随后尝试将其读取为文本.它不是 – 所以不要这样做.

如果必须将任意二进制数据转换为文本,请使用Convert.ToBase64StringConvert.FromBase64String.

public static class PBSerializer
{
    public static string Serialize(Type objType, object obj)
    {
        using (MemoryStream stream = new MemoryStream())
        {
            ProtoBuf.Serializer.Serialize(stream, obj);
            return Convert.ToBase64String(stream.ToArray());
        }
    }

    // Ideally change this to use a return value instead of an out parameter...
    public static void Deserialize(string serializedObj, out test obj)
    {
        byte[] data = Convert.FromBase64String(serializedObj);
        using (MemoryStream stream = new MemoryStream(data))
        {
            obj = ProtoBuf.Serializer.Deserialize<test>(stream);
        }
    }
网友评论