4

地形データをファイルに保存し、その一部だけをロードしたいと考えています。全体としてメモリに保存するには大きすぎるためです。実際、プロトブフがこの目的に適しているかどうかさえわかりません。

たとえば、次のような構造になります (文法的に無効である可能性があります。単純な基本しか知りません)。

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

    repeated int32 y = 3;
}

x値とz値は私のプログラムで利用できます。それらを使用して、同じxz (ファイル内) を持つ正しい Quad オブジェクトを見つけてy値を取得したいと思います。ただし、ParseFromIstream()でファイルを解析することはできません。ファイル全体をメモリにロードするためです (そう思う) が、私の場合はファイルが大きすぎます。

それで、protobuf は 1 つのオブジェクトをロードできますか?それをチェックするために私を送ってください。オブジェクトが間違っている場合は、2 つ目のオブジェクトを渡してください。

実際...私はただ尋ねることができます: ParseFromIstream()はファイル全体をメモリにロードしますか?

4

2 に答える 2

4

一部のライブラリではファイルを部分的に読み取ることができますが、Google が推奨する手法は、単純にファイルを複数のメッセージで構成することです。

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

プロトコル バッファは、大きなメッセージを処理するようには設計されていません。一般的な経験則として、それぞれが 1 メガバイトを超えるメッセージを扱う場合は、別の戦略を検討する時期かもしれません。

とはいえ、プロトコル バッファは、大規模なデータ セット内の個々のメッセージを処理するのに最適です。通常、大規模なデータ セットは実際には小さな断片の集まりに過ぎず、各小さな断片は構造化されたデータの断片である可能性があります。

したがって、メッセージの長さで区切られた長い一連のQuadメッセージをファイルに書き込むことができます。特定の をランダムにシークする必要がある場合Quadは、ある種のインデックスを追加することをお勧めします。

于 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 に答える