【发布时间】:2013-01-07 12:59:29
【问题描述】:
我成功序列化以下类的实例,但是当我在收到以下错误消息后立即尝试反序列化时:" Invalid field in source data: 0"。
我不知道它指的是什么,因为我直接找到了下面的类。我刚刚将 protobuf-net 版本更新为 2.00.614(运行时版本:2.0.50727)。
知道我是否可能忽略了一些琐碎的事情吗?
[ProtoContract]
public class TimeSeriesProperties
{
[ProtoMember(1)]
public string TimeSeriesName { get; private set; }
[ProtoMember(2)]
public string FileName { get; private set; }
[ProtoMember(3)]
public string TemplateName { get; private set; }
[ProtoMember(4)]
public int PacketLength { get; private set; }
[ProtoMember(5)]
public long FileSizeBytes { get; set; }
[ProtoMember(6)]
public long NumberRecords { get; set; }
[ProtoMember(7)]
public DateTime DateTimeStart { get; set; }
[ProtoMember(8)]
public DateTime DateTimeEnd { get; set; }
public TimeSeriesProperties()
{
}
public TimeSeriesProperties(string timeSeriesName, string fileName, string templateName, int PacketLength)
{
this.TimeSeriesName = timeSeriesName;
this.FileName = fileName;
this.TemplateName = templateName;
this.PacketLength = PacketLength;
}
}
public static byte[] Serialize_ProtoBuf<T>(T serializeThis)
{
using (var stream = new MemoryStream())
{
ProtoBuf.Serializer.Serialize<T>(stream, serializeThis);
return stream.GetBuffer();
}
}
public static T Deserialize_ProtoBuf<T>(byte[] byteArray)
{
using (var stream = new MemoryStream(byteArray))
{
return ProtoBuf.Serializer.Deserialize<T>(stream);
}
}
【问题讨论】:
-
这几乎总是意味着您正在过度阅读写入的数据,通常是通过错误处理
MemoryStream- 与protobuf-net无关;请问你能显示进行序列化/反序列化测试的代码吗? (理想情况下,添加一个@marc 评论,所以我知道回来看看) -
@MarcGravell,添加了这两个方法。
-
这种方法永远不会适用于 any protobuf 实现;最外面的消息不知道自己的长度是规范的一个特性——这是为了使片段可以通过连接进行合并。因此,默认情况下,它会读取到流的末尾(尽管大多数实现包括读取
n字节的机制,对于某些n)。在每个字段的末尾,它期望 要么 另一个字段头或 EOF。 0 从不是一个有效的字段头,所以尾随的零会破坏反序列化器。每一次。 -
顺便说一下,写入的数据量简直就是:
stream.Length -
这完全取决于上下文;在您展示的场景中(大多数
Streams 等),长度很容易获得,整个事情只是通过ToArray()或受约束的读取来固定。对于某些实现(例如NetworkStream发送多条消息),[Serialize|Deserialize]WithLengthPrefix是您的朋友。我不确定为什么你不知道序列化后的长度。你能扩展一下吗?如果这是文件开头的标题,*WithLengthPrefix应该可以正常工作。
标签: c# serialization deserialization protobuf-net