(あなたの質問を正しく理解し、私の回答があなたのユースケースに合っていることを願っています!)
プロトコル バッファ メッセージの任意のストリームをディスクに格納するための 1 つの手法は、すべてのフィールドが として定義されているラッパー メッセージを定義することですrepeated
(これは を意味optional
します)。次に、バイトを読み取るときに、ラッパー クラスのインスタンスを取得し、 hasX() メソッドを使用して、実際に持っているものを見つけます。あなたの場合のこのアプローチの問題は、ランダムアクセスも実際のストリーミングも得られないことです (タイプのすべてのメッセージFoo
が一緒になり、その後にすべてBar
の s が続きます)。データが大きすぎると、全体に収まりません。記憶にたくさん。
実際、あなたは基本的に、あらゆる種類のデータをストリーミングまたはランダム アクセスできるように保存するための方法論を求めています。これは、プロトコル バッファに固有の問題ではなく、一般的な問題です。
あなたの問題は次のとおりです。
- 区切りレコード... (注を参照)
- ...損傷を検出し、許容または修復できるような方法で...
- ...ランダムアクセスを許可するインデックスを維持しながら
おそらくインデックスを使用して何らかの整合性チェックを許可するでしょうが、それでもインデックスとデータが対応し、同期を維持するためのメカニズムが必要です。
したがって、これは理想的な解決策ではないかもしれませんが、特に整合性が問題となる場合に、目的を達成する 1 つの方法は、バイナリ データの格納を許可し、そのデータをすばやく返すことができるデータベースにこの情報を格納することです。ランダム アクセスとデータの整合性の問題は、データベース プロバイダーの責任になります。BLOB を格納できる従来のデータベースであれば、それを実行できますが、MongoDB などの NoSQL に格納することも検討します。
ノート
Protocol Buffers を慎重に定義する場合 (つまり、格納されるフィールドのタイプと長さを知っている場合) は、レコードの長さが変わらないため、実際にレコードを区切る必要はありません。ただし、これは Protocol Buffers の機能の 1 つ、つまり将来性のある性質を損なうことになります。メッセージ サイズが固定されるようにを設計した場合.proto
、新しいフィールドを追加することはできず、同じファイル形式に収まることができず、新しいメッセージはそれぞれ x バイトの後に始まると安全に言えます。