在下面的示例中如何使用ProtoBuf-net使用PrefixStyle获取长度数?
和PrefixStyle.Base128和PrefixStyle.Fixed32有什么区别?
谢谢!
PerfTest clone;
using (MemoryStream ms = new MemoryStream())
{
Serializer.SerializeWithLengthPrefix(ms, obj,PrefixStyle.Base128);
byte[] raw = ms.ToArray();
ms.Position = 0;
clone = Serializer.DeserializeWithLengthPrefix<PerfTest>(ms,PrefixStyle.Base128);
}
编辑:使用下面的代码,字节数组的长度为22.为什么TryReadLengthPrefix返回21?当然应该回22?
PerfTest clone;
using (MemoryStream ms = new MemoryStream())
{
Serializer.SerializeWithLengthPrefix(ms, obj,PrefixStyle.Base128);
byte[] raw = ms.ToArray();
ms.Position = 0;
int bArrayLen = ms.ToArray().Length; //returns 22
int len;// set to 21. Why not 22?
Serializer.TryReadLengthPrefix(ms, PrefixStyle.Base128,out len);
clone = Serializer.DeserializeWithLengthPrefix<PerfTest>(ms,PrefixStyle.Fixed32);
}
答案 0 :(得分:4)
Fixed32总是使用4个字节作为长度前缀 - 这对于人们手动打包消息似乎并不少见(实际上,由于重复请求,我甚至不得不在某些时候添加不同的端版本。)
首选项应该是Base128,它使用“varint”编码,因此较小的数字需要较少的空间来编码。此外,此前缀样式可用于使一系列对象与具有repeated
字段的单个对象进行线程兼容,该字段具有一些有用的应用程序。
重新获得长度;如果您使用的是DeserializeWithLenghPrefix
或DeserializeItems
,则不需要 - 它会在内部处理它。但如果您需要,请查看Serializer.TryReadLengthPrefix
。
澄清一下:*WithLengthPrefix
方法的目的是允许在单个流中分离不同的对象/消息 - 最常见的是:网络套接字。这是必要的,因为协议本身否则假定整个流是单个消息,因此在流/套接字关闭之前会继续尝试读取。
重新22对21字节;这是因为长度前缀本身需要一些长度:)实际上如果数组是22我有点惊讶有效载荷不是20 - I字节字段朝向(使组合流本身成为有效的protobuf流),1字节长度和20字节有效负载。我现在正在使用手机,所以我无法运行样本进行调查;尽管如此,可以省略字段头(可选) - 因此它可以是1字节长度,21字节有效负载。我稍后会看。