我显然做了一些基本的错误,但我无法弄明白,也找不到文档. 我正在尝试使用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.ToBase64String
和Convert.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); } }