反序列化“长” c# 的带有 protobuf 的字符串对我来说不能正常工作
我显然做了一些基本的错误,但我无法弄清楚并且找不到文档。
我正在尝试 Marc Gravell 的 .NET 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 和 444 版本。 450,结果相同。
谢谢。
I'm obviously doing something basic wrong but I can't figure it out and don't find documentation.
I'm experimenting with proto-buf for .NET by Marc Gravell, and trying to serialize and deserialize objects. Once an object contains a string which is "too long" (didn't try to pinpoint the size threshold but it's few hundred bytes) the string doesn't deserialize properly for me.
This is my code:
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 is not identical to var1.s2 - it has an extra character at the beginning of the string and truncates the majority of the end of the string. If however, I change the length of var1.s2 to a small number (say 52 instead of 520 chars) my problem goes away but I need to be able to serialize long strings.
I assume it has to do with something I do wrong with the setting the PrefixStyle (?) or perhaps I'm not using the right encoding (?). However, trial and error didn't help me sort it out.
I'm using .NET 3.5 and tried it with versions 444 & 450 with the same result.
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您正在序列化二进制数据 - 但然后尝试将其像文本一样读取。事实并非如此——所以不要这样做。
如果您必须将任意二进制数据转换为文本,请使用<代码>Convert.ToBase64String 和
Convert.FromBase64String
。You're serializing binary data - but then trying to read it as if it were text. It's not - so don't do that.
If you have to turn arbitrary binary data into text, use
Convert.ToBase64String
andConvert.FromBase64String
.