4

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

例如,我会有这样的结构(在语法上可能无效,我只知道简单的基础知识):

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

    repeated int32 y = 3;
}

xz值在我的程序中可用,通过使用它们,我想找到具有相同xz(在文件中)的正确 Quad 对象以获得y值。但是,我不能只用ParseFromIstream()解析文件,因为(我认为是这样)它将整个文件加载到内存中,但就我而言,文件太大了。

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

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

4

2 回答 2

4

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

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

协议缓冲区不是为处理大消息而设计的。作为一般经验法则,如果您要处理的消息均大于 1 兆字节,则可能是时候考虑另一种策略了。

也就是说,Protocol Buffers 非常适合处理大型数据集中的单个消息。通常,大型数据集实际上只是小片段的集合,其中每个小片段都可能是结构化的数据片段。

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

于 2013-02-16T08:45:07.213 回答
2

这取决于您使用的实现。有些具有“按序列读取”的 API。例如,假设您将其存储为“重复四边形”,那么使用 protobuf-net 将是:

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

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

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

于 2013-02-15T17:37:27.473 回答