如何使用 PrefixStyle 和 ProtoBuf-net 获取长度数?
在下面的示例中,如何使用 PrefixStyle 和 ProtoBuf-net 获取长度数字?
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);
}
in the example below how do i get the length number using PrefixStyle with ProtoBuf-net?
and what's the difference between PrefixStyle.Base128 and PrefixStyle.Fixed32?
Thanks!
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);
}
Edit: Using the code below the byte array has a length of 22. Why does TryReadLengthPrefix return 21? Surely is should return 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);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
Fix32 总是使用 4 个字节作为长度前缀 - 这对于手动打包消息的人来说似乎并不罕见(事实上,由于重复请求,我什至不得不在某些时候添加不同的字节序版本)。
不过,首选应该是 Base128,它使用“varint”编码,因此较小的数字需要较少的编码空间。此外,此前缀样式可用于使对象序列与具有
repeated
字段的单个对象有线兼容,这有一些有用的应用程序。重新获取长度;如果您使用
DeserializeWithLenghPrefix
或DeserializeItems
您不应该需要 - 它会在内部处理它。但如果您需要这个,请查看Serializer.TryReadLengthPrefix
。澄清一下:
*WithLengthPrefix
方法的目的是允许在单个流中分离不同的对象/消息 - 最常见的是:网络套接字。这是必要的,因为协议本身假设整个流是单个消息,因此将继续尝试读取直到流/套接字关闭。重新比较 22 与 21 字节;这是因为长度前缀本身需要一定的长度:)实际上,如果数组是 22,我有点惊讶有效负载不是 20 - I 字节字段(使组合流本身成为有效的 protobuf 流),1 字节长度和 20 字节负载。我目前使用的是移动设备,因此无法运行示例进行调查;不过,可以省略字段标头(可选) - 因此它可以是 1 字节长度,21 字节有效负载。我稍后再看看。
Fixed32 always uses 4 bytes for the length prefix - this seems to be not uncommon for people packing messages manually (indeed, I even had to add different-endian versions at some point, due to repeat requests).
The preference though should be Base128, which uses "varint" encoding, so small numbers take less space to encode. Additionally, this prefix style can be used to make a sequence of objects wire-compatible with a single object with a
repeated
field, which has some useful applications.Re getting the length; if you are using
DeserializeWithLenghPrefix
orDeserializeItems
you shouldnt need to - it handles it internally. But if you need this, look atSerializer.TryReadLengthPrefix
.To clarify: the purpose of the
*WithLengthPrefix
methods is to allow separation of different objects/messages in a single stream - most commonly: network sockets. This is necessary because the protocol itself otherwise assumes an entire stream is a single message, so would keep trying to read until the stream/socket was closed.Re the 22 vs 21 bytes; that is because the length prefix itself takes some length :) actually if the array is 22 I'm a little surprised the payload isn't 20 - I byte field headed (to make the composed stream itself a valid protobuf stream), 1 byte length, and 20 bytes payload. I'm on a mobile at the moment, so I can't run the sample to investigate; it is possible to omit the field-header (optionally), though - so it could be 1 byte length, 21 bytes payload. I'll look later.