如何从C ++中的protobuf中的`GzipInputStream`中读取特定大小的消息?

时间:2014-05-30 05:39:56

标签: c++ gzip protocol-buffers

我想从网络套接字读取特定大小的消息。大小在消息之前编码。尺寸+消息使用GzipOutputStream进行了解压缩。

以下是我的解码器的简化示例代码:

unsigned size;
GzipInputStream gzip_stream(&file_input_stream_, GzipInputStream::ZLIB);
{
  CodedInputStream coded_stream(&gzip_stream);
  coded_stream.ReadVarint32(&size);
}

message->ParseFromBoundedZeroCopyStream(&gzip_stream, size);

MessageLite::ParseFromBoundedZeroCopyStream()的文档中有相反的陈述:

  • 从给定的零拷贝输入流中读取协议缓冲区,期望消息准确地"大小"字节长
  • 如果成功,将从输入中消耗这么多字节。

所以,我很困惑 - 这个函数会从流中读取size个字节,还是期望size个字节的消息? - 我建议使用前者,因为我无法从同一个套接字中正确读取两条消息。


问题:

如何从SerializeAsString().size()正确阅读特定尺寸(GzipInputStream)的讯息?

1 个答案:

答案 0 :(得分:1)

要点不是自相矛盾的。由于ParseFromBoundedZeroCopyStream不知道它从哪种流中读取,因此文档当然是指在解压缩后从流中获取的数据大小。它将从流中准确读取size 未压缩的字节,将它们解释为单个消息。如果您只知道邮件的压缩大小,则无法使用此方法;你必须做一些更复杂的事情,例如将GzipInputStream分层放在LimitingInputStream

之上

(另请注意,如果方法返回false表示失败,那么它可能已经提前停止读取,使您的流处于不确定状态。如果这是一个问题,您将不得不做一些更复杂的事情。即使出现解析错误,也要确保读取完整大小,例如自己设置LimitingInputStream并在解析失败后明确地排除数据。)