【问题标题】:Storing unspecified Protocol Buffer messages in another PB message?将未指定的协议缓冲区消息存储在另一个 PB 消息中?
【发布时间】:2011-12-28 22:32:57
【问题描述】:

我正在尝试使用 Google 的协议缓冲区(Java 中)编写“可扩展”文件格式。 API 应该可以读取数据,并返回一个“容器”消息(已知类型),其中包含一些其他类型未知的消息(但 API 调用者知道这些消息)。

在 PB 定义和 Java 代码中,有哪些可能的方法来做到这一点?

一种似乎显而易见的方法是将实现未指定消息的类名以及包含消息数据的字节数组存储在“容器”消息中。但我不知道如何使用反射从它的类和字节数组创建消息。

另一种方法可能是使用“扩展”机制,但我真的不知道如何做到这一点?

【问题讨论】:

    标签: java protocol-buffers


    【解决方案1】:

    如果你有正确的类名和字节数组,你可以通过反射实例化对应的Builder,然后在上面调用mergeFrom(byte[])方法。

    【讨论】:

    • 谢谢! “CLASS x = CLASS.newBuilder().mergeFrom(BYTES).build()” 在接受您的回答之前,我将稍等片刻,看看是否有人也可以告诉我如何使用扩展来做到这一点...
    【解决方案2】:

    我们做了类似的事情,但发出了如下一般信息:

    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> 并将其与标头信息一起返回给应用程序。在应用程序之间,您需要确保正确获取名称和类型。

    【讨论】:

    • 关于“快速序列化/反序列化(不需要反射)”,反射部分应该是最小的。实际上,您只需要在遇到的每个类中执行一次。您为其实例化的 Builder 可以重复使用。除非每条消息都不一样,或者消息的数量非常少,否则反射的开销应该可以忽略不计。
    • 确实可以重复使用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-10-19
    • 1970-01-01
    • 2011-07-31
    • 2013-09-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多