我正在使用ProtoBuf.NET来序列化/反序列化某些类。我发现在反序列化时,我得到一个损坏的字节[](额外的0)。在您提出之前,是的,我需要ProtoBuf API的 * WithLengthPrefix()版本,因为ProtoBuf部分位于自定义流的开头:)。
无论如何,我看到了
Original object is (JSON depiction):
{"ByteArray":"M+B6q+PXNuF8P5hl","ByteArray2":"DmErxVQ2y87IypSRcfxcWA==","K":2,"V
":1.0}
Protobuf: Raw Hex (42 bytes):
29-2A-20-0A-0C-33-E0-7A-AB-E3-D7-36-E1-7C-3F-98-65-12-10-0E-61-2B-C5-54-36-CB-CE
-C8-CA-94-91-71-FC-5C-58-08-02-15-00-00-80-3F
Regenerated object is (JSON depiction):
{"ByteArray":"AAAAAAAAAAAAAAAAM+B6q+PXNuF8P5hl","ByteArray2":"DmErxVQ2y87IypSRcf
xcWA==","K":2,"V":1.0}
AAA*A
成员中的额外ByteArray
在base64中基本上是十六进制0x00。
app逻辑类似于
static void Main(string[] args)
{
var parent = new Parent();
parent.Init();
Console.WriteLine("\nOriginal object is (JSON depiction):");
Console.WriteLine(JsonConvert.SerializeObject(parent));
using (var ms = new MemoryStream())
{
Serializer.SerializeWithLengthPrefix(ms, parent, PrefixStyle.Base128);
byte[] bytes2 = ms.ToArray();
var hex2 = BitConverter.ToString(bytes2);
Console.WriteLine("\nProtobuf: Hex ({0} bytes):\n{1}", bytes2.Length, hex2);
ms.Seek(0, SeekOrigin.Begin);
var backFirst = Serializer.DeserializeWithLengthPrefix<Parent>(ms,PrefixStyle.Base128);
Console.WriteLine("\nRegenerated object is (JSON depiction):");
Console.WriteLine(JsonConvert.SerializeObject(backFirst));
}
}
DTO课程
[DataContract]
[ProtoContract]
internal class Parent : Child
{
[DataMember(Name = "ByteArray", Order = 10)]
[ProtoMember(1)]
public byte[] ByteArray { get; set; }
[DataMember(Name = "ByteArray2", Order = 30, EmitDefaultValue = false)]
[ProtoMember(2)]
public byte[] ByteArray2 { get; set; }
public Parent()
{
ByteArray = new byte[12];
}
internal void Init(bool bindRow = false)
{
base.Init();
var rng = new RNGCryptoServiceProvider();
rng.GetBytes(ByteArray);
ByteArray2 = new byte[16];
rng.GetBytes(ByteArray2);
}
}
[DataContract]
[ProtoContract]
[ProtoInclude(5, typeof(Parent))]
public class Child
{
[DataMember(Name = "K", Order = 100)]
[ProtoMember(1)]
public Int32 K { get; set; }
[DataMember(Name = "V", Order = 110)]
[ProtoMember(2)]
public float V { get; set; }
internal void Init()
{
K = 2;
V = 1.0f;
}
}
我确实看到当我将ByteArray = new byte[12]
从Parent
构造函数移到Init()
方法中时,ProtoBuf工作正常。但是,我们有应用程序逻辑,以防止在实际版本中(相对于您在上面看到的SO修剪代码)。
我们做错了什么或者这是ProtoBuf中的错误吗?
答案 0 :(得分:4)
我们走了:
public Parent()
{
ByteArray = new byte[12];
}
注意:protobuf(由谷歌设计)既可以附加也可以合并。其中append / merge与“append”同义(对于列表/数组等)。
两个选项(两者都可以通过属性):
[ProtoContract(SkipConstructor = true)]
[ProtoMember(1, OverwriteList = true)]
还有其他选择,但那些是我倾向于的。
你注意到实际代码中的数组初始化是不同的,但是:我无法评论我看不到的代码。
答案 1 :(得分:0)
我遇到了同样的问题,我的Bytestring
数据实际上是从服务器获取的XML数据,因此在我的应用程序中我已经有一个XML Serialaizer
,因此我决定使用它我发现没有为serializer
引入新的Photobuf
并修饰我的所有模型,而是发现此任务非常耗时。
这是我的功能,它将deserialize
Bytestring
。
public SceneDTO ParseSceneAsyncFromByteString(ByteString byteStringData) {
var serializer = new CustomXmlSerializer(typeof(SceneDTO), _timingManager);
serializer.UnknownNode += OnUnknownNode;
serializer.UnknownAttribute += OnUnknownAttribute;
var ms = new MemoryStream(byteStringData.ToByteArray());
var scene = (SceneDTO) serializer.Deserialize(ms);
serializer.UnknownNode -= OnUnknownNode;
serializer.UnknownAttribute -= OnUnknownAttribute;
return scene;
}
我遵循此方法的另一个原因是在使用Photobuf
serializer
之后出现了以下错误。
源数据中的意外末端组;这通常意味着来源 数据损坏了photobuf解串器
即使解决了这个问题,我的模型数据也始终为空,由于我已经有了一个可行的解决方案,因此我决定不花费很多时间来解决该问题。