【问题标题】:How to read fixed32 integer using protobuf-net?如何使用 protobuf-net 读取 fixed32 整数?
【发布时间】:2011-12-07 08:28:31
【问题描述】:

这似乎是一个基本问题,但我有疑问可能是因为我使用 2 个不同的库来写入和读取数据。我的 Write 程序是用 C++ 编写的,它使用 google 的协议缓冲区库。我的阅读器是用 .NET c# 实现的。

在写程序中,我写了一个文件头如下。

coded_output->WriteLittleEndian32(BIN_START_MAGIC_NUMBER);
coded_output->WriteLittleEndian32(major_version);
coded_output->WriteLittleEndian32(minor_version);
coded_output->WriteVarint32(strlen(_region));
coded_output->WriteRaw(_region, strlen(_region));
coded_output->WriteLittleEndian32(_offset);

C#中读取上述字段的对应函数是什么?我了解如何读取协议缓冲区消息,但不确定如何读取上述数据。

问候, 阿洛克

【问题讨论】:

  • 分配文件你也写这些到文件流,而不是使用msdn.microsoft.com/en-us/library/system.io.filestream.read.aspx你可以指定要读取的内容,例如WriteLittleEndian32是32位
  • @nikolaMM94 同时读取 4 个字节非常简单(尽管 即使 实际上并不像调用 Read 传递 count = 4 那样简单),字符串明显更棘手,因为你还需要处理 varint 编码。
  • 我支持我将能够读取 Little endian 32 位整数。 Varint32 整数呢?我想这将是编码的,并且无法直接由 FileStream 读取。 C#中是否有对应的读取函数?
  • @Marc,正是我关于字符串的问题。您能建议我在哪里可以找到这方面的文档吗?
  • @Marc,现在查看您的回复。

标签: c# c++ serialization protocol-buffers


【解决方案1】:

该文件头不是有效的 protobuf 序列,因此 protobuf-net 中的标准读取机制无法读取它 - 实际上,ProtoReader 不会让自己得到进入读取状态,因为它是无效的。然而!要读取 little-endian 32 位数字,您可能可以使用:

int x, int y; // ignore
int value = ProtoReader.ReadLengthPrefix(stream, false, PrefixStyle.Fixed32,
                      out x, out y);

假设编码流使用标准 protobuf 约定,字符串被写为 varint 长度前缀,然后是 UTF-8,所以你可以使用:

int x, int y; // ignore
int length = ProtoReader.ReadLengthPrefix(stream, false, PrefixStyle.Base128,
                      out x, out y);
byte[] bytes = new byte[length];
int read, offset = 0;
while(length > 0 && (read = stream.Read(bytes, offset, length)) > 0) {
    offset += read;
    length = read;
}
if(length > 0) throw new EndOfStreamException();
string s = Encoding.UTF8.GetString(bytes);

如果您真的愿意,我可能会更方便地为您打包;它们目前没有公开,因为 那不是 protobuf ;p

【讨论】:

  • WriteVarint32() 是否指定字符串的大小?
  • @nikolaMM94 WriteVarint32 映射到带有 Base128 的 ReadLengthPrefix(我真的必须将其重命名为 varint...)
  • 感谢您的回复。结果很好。我可以使用提供的解决方案。
  • 我知道这不是一个有效的 protobuf 序列,但我认为许多开发人员会使用此代码,因此可能更容易将其打包为函数。读取具有给定长度前缀的字符串?
  • @Alok 如我上面的第二个示例所示。如果您的意思是“您可以添加方法来更方便地执行此操作吗”...可能是的;p
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-30
  • 1970-01-01
  • 2013-06-11
  • 2012-12-28
  • 1970-01-01
相关资源
最近更新 更多