开发学院

您的位置:首页>教程>正文

教程正文

Protobuf 技术

  本页描述了一些用于处理Protocol Buffer的常用设计模式。您还可以向协议缓冲区讨论组发送设计和使用问题。

流式传输多条消息

  如果您想将多条消息写入一个文件或流中,您可以跟踪一条消息的结束位置和下一条消息的开始位置。Protocol Buffer wire格式不是自定界(self-delimiting)的,因此Protocol Buffer解析器无法自行确定消息的结束位置。解决这个问题最简单的方法是在写消息本身之前写下每个消息的长度。当您重新读入消息时,先读取长度,然后将字节读入单独的缓冲区,然后从该缓冲区解析。(如果您想避免将字节复制到单独的缓冲区,请查看CodedInputStream类(在C++和Java中),该类可以被告知将读取限制在一定数量的字节。)

大型数据集

  Protocol Buffer不是为处理大消息而设计的。一般来说,如果你处理的消息都大于一兆字节,那么是时候考虑另一种策略了。

  换句话说,Protocol Buffer非常适合处理大数据集中的单个消息。通常,大数据集实际上只是一小块的集合,其中每个小块可能是一个结构化的数据块。尽管Protocol Buffer不能同时处理整个集合,但是使用Protocol Buffer来编码每一个片段大大简化了您的问题:现在您只需要处理一组字节字符串,而不是一组结构。

  Protocol Buffer不包括对大数据集的任何内置支持,因为不同的情况需要不同的解决方案。有时候一个简单的记录列表就可以了,而其他时候你可能想要一个更像数据库的东西。每个解决方案都应该作为一个独立的库来开发,这样只有那些需要的人才需要支付成本。

自描述信息

  Protocol Buffer不包含它们自己类型的描述。因此,只给出一个原始消息,而没有相应的定义其类型的.proto文件,所以我们很难提取任何有用的数据。

  但是,请注意. proto文件的内容本身可以使用Protocol Buffer来表示。源代码包中的文件src/google/protobuf/descriptor.proto定义了所涉及的消息类型。协议可以输出一个文件描述集合,它代表一组.proto文件:使用--descriptor_set_out选项。有了这个,您可以定义这样一个自描述的协议消息:

syntax = "proto3";

import "google/protobuf/any.proto";
import "google/protobuf/descriptor.proto";

message SelfDescribingMessage {
  // Set of FileDescriptorProtos which describe the type and its dependencies.
  google.protobuf.FileDescriptorSet descriptor_set = 1;

  // The message and its type, encoded as an Any message.
  google.protobuf.Any message = 2;
}

  通过使用像DynamicMessage这样的类(在C++和Java中可用),您可以编写工具来操作自描述消息。

  尽管如此,Protocol Buffer 库没有包含这一功能的原因是因为我们从未在谷歌内部使用过它。

  这种技术需要使用描述符支持动态消息。在使用自描述消息之前,请检查您的平台是否支持此功能。

  本页面的内容是根据知识共享属性3.0(cc3.0)许可证许可的,代码示例是根据Apache 2.0许可证许可的,除非另有说明。有关详细信息,请参见Google网站的策略。Java是甲骨文和/或其附属公司的注册商标。