【问题标题】:How to read the message of a specific size from `GzipInputStream` in protobuf in C++?如何从 C++ protobuf 中的“GzipInputStream”中读取特定大小的消息?
【发布时间】:2014-05-30 05:39:56
【问题描述】:

我想从网络套接字读取特定大小的消息。大小在消息本身之前进行编码。大小+消息用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 字节,还是会期待size 字节的消息? - 我建议前者,因为我无法从同一个套接字正确读取两条消息。


问题:

如何正确读取来自GzipInputStream的特定大小(SerializeAsString().size())的消息?

【问题讨论】:

    标签: c++ gzip protocol-buffers


    【解决方案1】:

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

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

    【讨论】:

      猜你喜欢
      • 2011-09-07
      • 1970-01-01
      • 2016-06-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多