文档详情

Protobuf使用手册

ali****an
实名认证
店铺
DOC
235.50KB
约35页
文档ID:121588670
Protobuf使用手册_第1页
1/35

Protobuf使用手册第1章 定义.proto 文件首先我们需要编写一个 proto 文件,定义我们程序中需要处理的结构化数据,在 protobuf 的术语中,结构化数据被称为 Messageproto 文件非常类似 java 或者 C 语言的数据定义,可以使用C或C++风格的注释下面是一个proto文件的例子package tutorial;option java_package = "com.example.tutorial";option java_outer_classname = "AddressBookProtos";message Person {required string name = 1;required int32 id = 2; // Unique ID number for this person.optional string email = 3;enum PhoneType { MOBILE = 0; HOME = 1; WORK = 2;}message PhoneNumber { required string number = 1; optional PhoneType type = 2 [default = HOME];}repeated PhoneNumber phone = 4;}// Our address book file is just one of these.message AddressBook {repeated Person person = 1;}一个proto文件主要包含package定义、message定义和属性定义三个部分,还有一些可选项。

1.1 定义packagePackage在c++中对应namespace对于Java,包声明符会变为java的一个包,除非在.proto文件中提供了一个明确有java_package1.2 定义messageMessage在C++中对应classMessage中定义的全部属性在class中全部为private的Message的嵌套使用可以嵌套定义,也可以采用先定义再使用的方式Message的定义末尾可以采用java方式在不加“;”,也可以采用C++定义方式在末尾加上“;”,这两种方式都兼容,建议采用java定义方式向.proto文件添加注释,可以使用C/C++/java风格的双斜杠(//)语法格式1.3 定义属性属性定义分为四部分:标注+类型+属性名+属性顺序号+[默认值],其示意如下所示标注类型属性名属性顺序号[默认值]requiredstringname= 1[default=””]; 其中属性名与C++和java语言类似,不再解释;下面分别对标注、类型和属性顺序号加以详细介绍其中包名和消息名以及其中变量名均采用java的命名规则——驼峰式命名法,驼峰式命名法规则见附件11.3.1 标注标注包括“required”、“optional”、“repeated”三种,其中required表示该属性为必选属性,否则对应的message“未初始化”,debug模式下导致断言,release模式下解析失败;optional表示该属性为可选属性,不指定,使用默认值(int或者char数据类型默认为0,string默认为空,bool默认为false,嵌套message默认为构造,枚举则为第一个)repeated表示该属性为重复字段,可看作是动态数组,类似于C++中的vector。

如果为optional属性,发送端没有包含该属性,则接收端在解析式采用默认值对于默认值,如果已设置默认值,则采用默认值,如果未设置,则类型特定的默认值为使用,例如string的默认值为””1.3.2 类型Protobuf的属性基本包含了c++需要的所有基本属性类型protobuf属性C++属性java属性备注doubledoubledouble固定8个字节floatfloatfloat固定4个字节int32int32int32使用变长编码,对于负数编码效率较低,如果经常使用负数,建议使用sint32int64int64int64使用变长编码,对于负数编码效率较低,如果经常使用负数,建议使用sint64uint32uint32int使用变长编码uint64uint64long使用变长编码sint32int32int采用zigzag压缩,对负数编码效率比int32高sint64int64long采用zigzag压缩,对负数编码效率比int64高fixed32uint32int总是4字节,如果数据>2^28,编码效率高于unit32fixed64uint64long总是8字节,如果数据>2^56,编码效率高于unit32sfixed32int32int总是4字节sfixed64int64long总是8字节boolboolbooleanstringstringString一个字符串必须是utf-8编码或者7-bit的ascii编码的文本bytesstringByteString可能包含任意顺序的字节数据1.3.2.1 Union类型定义Protobuf没有提供union类型,如果希望使用union类型,可以采用enum和optional属性定义的方式。

例如,如果已经定义了Foo、Bar、Baz等message,则可以采用如下定义message OneMessage { enum Type { FOO = 1; BAR = 2; BAZ = 3; } // Identifies which field is filled in. required Type type = 1; // One of the following will be filled in. optional Foo foo = 2; optional Bar bar = 3; optional Baz baz = 4;}1.3.3 属性顺序号属性顺序号是protobuf为了提高数据的压缩和可选性等功能定义的,需要按照顺序进行定义,且不允许有重复1.4 其它可选项Protocol Buffer允许我们在.proto文件中定义一些常用的选项,这样可以指示Protocol Buffer编译器帮助我们生成更为匹配的目标语言代码Protocol Buffer内置的选项被分为以下三个级别:1. 文件级别,这样的选项将影响当前文件中定义的所有消息和枚举2. 消息级别,这样的选项仅影响某个消息及其包含的所有字段。

3. 字段级别,这样的选项仅仅响应与其相关的字段1.4.1 java_package可选项java_package (file option): 是文件级别的选项,表明生成java类所在的包如果在.proto文件中没有明确的声明java_package,就采用默认的包名当然了,默认方式产生的 java包名并不是最好的方式,按照应用名称倒序方式进行排序的如果不需要产生java代码,则该选项将不起任何作用与此同时,生成的Java文件也将会自动存放到指定输出目录下的com/example/foo子目录中如:option java_package = "com.example.foo";1.4.2 java_outer_classname可选项java_outer_classname (file option): 是文件级别的选项,表明想要生成Java类的名称如果在.proto文件中没有明确的java_outer_classname定义,生成的class名称将会根据.proto文件的名称采用驼峰式的命名方式进行生成如(foo_bar.proto生成的java类名为FooBar.java),如果不生成java代码,则该选项不起任何作用。

如:option java_outer_classname = "Ponycopter";注:主要是因为Java中要求同一个.java文件中只能包含一个Java外部类或外部接口,而C++则不存在此限制因此在.proto文件中定义的消息均为指定外部类的内部类,这样才能将这些消息生成到同一个Java文件中在实际的使用中,为了避免总是输入该外部类限定符,可以将该外部类静态引入到当前Java文件中,如:import static pany.project.LYPhoneMessage.*1.4.3 *_generic_services可选项cc_generic_services, java_generic_services, py_generic_services (file options): 在C++、java、python中protocol buffer编译器是否应该基于服务定义产生抽象服务代码由于历史遗留问题,该值默认是true但是自2.3.0版本以来,它被认为通过提供代码生成 器插件来对RPC实现更可取,而不是依赖于“抽象”服务// This file relies on plugins to generate service code.option cc_generic_services = false;option java_generic_services = false;option py_generic_services = false;1.4.4 message_set_wire_format可选项message_set_wire_format (message option):如果该值被设置为true,该消息将使用一种不同的二进制格式来与Google内部的MessageSet的老格式相兼容。

对于Google外部的用户来说,该选项将不会被用到如下所示:message Foo { option message_set_wire_format = true; extensions 4 to max;}1.4.5 import可选项Import可选项用于包含其它proto文件中定义的message或enum类型等标准格式如下import “phonetype.proto”;使用时,import的文件必须与当前文件处于同一个文件夹下,protoc无法完成不处于同一个文件夹下的import选项1.4.6 optimize_foroptimize_for (fileoption): 是文件级别的选项,可以被设置为 SPEED, CODE_SIZE,or LITE_RUNTIME,缺省情况下是SPEED这些值将通过如下的方式影响C++及java代码的生成:SPEED (default): protocol buffer编译器将通过在消息类型上执行序列化、语法分析及其他通用的操作这种代码是最优的CODE_SIZE: protocol buffer编译器将会产生最少量的类,通过共享或基于反射的代码来实现序列化、语法分析及各种其它操作。

采用该方式产生的代码将比SPEED要少得多, 但是操作要相对慢些当然实现的类及其对外的API与SPEED模式都是。

下载提示
相似文档
正为您匹配相似的精品文档