protobuf可以部分阅读吗?

时间:2013-02-15 16:57:06

标签: c++ protocol-buffers

我想将我的地形数据保存到文件中并仅加载它的某些部分,因为它太大而无法将其存储在整个内存中。实际上我甚至都不知道protobuf是否适合这个目的。

例如,我会有一个类似的结构(可能是无效的,我只知道简单的基础知识):

message Quad {
    required int32 x = 1;
    required int32 z = 2;

    repeated int32 y = 3;
}

x z 值在我的程序中可用并且使用它们我想找到具有相同 x 和 z (在文件中)获取 y 值。但是,我不能用 ParseFromIstream()解析文件,因为(我认为是这样)它将整个文件加载到内存中,但在我的情况下文件太大了。

那么,protobuf能够加载一个对象,发送给我检查它,如果对象错误,请给我第二个?

实际上......我可以问: ParseFromIstream()是否将整个文件加载到内存中?

2 个答案:

答案 0 :(得分:2)

这取决于您使用的实施方式。有些人“读作序列”API。例如,假设您将其存储为“重复Quad”,那么使用protobuf-net将是:

int x = ..., y = ...;
var found = Serializer.DeserializeItems<Quad>(source)
            .Where(q => q.x ==x && q.y == y);

重点是:它产生一个假脱机(不是一次全部加载)和短路序列。

我不知道具体的c ++ api,但我希望它有类似的东西 - 但最坏的情况是你可以解析varint头并准备一个长度上限的流。

答案 1 :(得分:2)

虽然有些库允许您部分阅读文件,但Google推荐的技术只是让文件包含多条消息:

https://developers.google.com/protocol-buffers/docs/techniques

  

协议缓冲区不是为处理大型邮件而设计的。作为一般经验法则,如果   你正在处理每个大于兆字节的消息,可能是时候考虑了   替代战略。

     

也就是说,协议缓冲区非常适合处理大数据中的单个消息   组。通常,大型数据集实际上只是一小块的集合,每个小块都很小   件可能是一个结构化的数据。

因此,您可以将一长串Quad消息写入文件,并以消息的长度分隔。如果您需要随机查找特定的Quad,您可能需要添加某种索引。