2011-12-28 6 views
1

Googleのプロトコルバッファ(Java)を使用して「拡張可能な」ファイル形式を作成しようとしています。 APIがデータを読み込み、知られていないタイプの(API呼び出し側に知られている)その他のメッセージを含む(既知の型の)「コンテナ」メッセージを返すことは可能でなければなりません。別のPBメッセージに不特定のプロトコルバッファメッセージを格納していますか?

これを行うには、PB定義とJavaコードの両方でどのような方法がありますか?

明白な1つの方法は、メッセージデータを含むバイト配列と共に、不特定のメッセージを実装するクラス名を「コンテナ」メッセージに格納することです。しかし、私はリフレクションを使って、クラスとバイト配列からメッセージを作成する方法を知らない。

もう1つの方法はおそらく "拡張"メカニズムを使用することですが、実際にこれを行う方法はありませんか?

答えて

3

クラス名とバイト配列が正しい場合は、リフレクションによって対応するBuilderをインスタンス化し、mergeFrom(byte[])メソッドを呼び出すことができます。

+0

ありがとうございます! "CLASS x = CLASS.newBuilder()。mergeFrom(BYTES).build()"答えを受け入れる前に、誰かが拡張機能でどうやってそれを行うか教えてもらえるかどうか少し調べるつもりです... –

0

私たちは似た何かをしたが、次のような一般的なメッセージを作っ:

message GenericMessage { 
    required int32 id = 1; 
    // further generic message headers 

    message IntegerVariable { 
    required string name = 1; 
    optional int32 data = 2; 
    } 
    repeated IntegerVariable integerVars = 2; 

    message IntegerArrayVariable { 
    required string name = 1; 
    repeated int32 data = 2; 
    optional int32 length = 3; 
    } 
    repeated IntegerArrayVariable integerArrayVars = 3; 

    message DoubleVariable { 
    required string name = 1; 
    optional double data = 2; 
    } 
    repeated DoubleVariable doubleVars = 4; 

    ... 

    message RawVariable { 
    required string name = 1; 
    optional bytes data = 2; 
    } 
    repeated RawVariable rawVars = x; 
} 

これは、あなたは多くの可能な例のために一つのバッファを使用することができますし、まだ(なしあなたに高速なシリアライズ/デシリアライゼーションのの利点を提供します反射が必要)。バッファには、必須または任意のマークを付けることができるヘッダ変数と、複数の繰返しペイロード変数を含めることができます。これは非常に一般的であるにもかかわらず、メッセージがまだ非常に小さくなることを可能にします。

これらのメッセージを処理するために追加のレイヤーを作成する場合は、メッセージをHashMap<String, Object>に処理し、ヘッダー情報と共にアプリケーションに返すことをお勧めします。アプリケーション間で、名前とタイプを正しく取得する必要があります。

+0

「高速シリアル化/デシリアライゼーション(反射が不要)」に関しては、反射部分は最小限に抑える必要があります。現実的には、遭遇するクラスごとに1回だけ行う必要があります。そのためにインスタンス化するBuilderを再利用することができます。すべてのメッセージが異なるか、またはメッセージの数が非常に少ない場合を除き、Reflectionのオーバーヘッドはごくわずかです。 – rfeak

+0

それは本当に再利用できます。 – Andreas

関連する問題