示例简介
本例是一个可以读写联系信息的“地址本”应用,每个人在地址本里有个id、名字、邮箱地址和联系电话。
编译器安装
- window
- 下载protocol compiler
- 将下载到的可执行文件放置到相应目录,并配置到环境变量path中
- linux
略
定义protocol格式
为了创建地址本应用,我们需要开始定义一个.proto文件。.proto文件定义很简单:为需要序列化的数据都添加一个message,然后指定message中字段指定类型和名称。具体定义如下所示:
package tutorial;
option java_package = "com.example.tutorial";
option java_outer_classname = "AddressBookProtos";
message Person {
required string name = 1;
required int32 id = 2;
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;
}
message AddressBook {
repeated Person person = 1;
}
如你所见,上面的语法与C++和Java非常相似。下面我们一步步分析该文件:
- package:避免不同的项目命名冲突
java_package和java_outer_classname
- java_package:指定生成的类会在哪个包下,如果不显示指定,使用package的声明
- java_outer_classname:指定.proto文件包含的所有类的外部类名称,如果不显示指定,使用.ptoto文件名称的驼峰形式作为类名
message:一个message是一系列字段的集合。
- field
- type:bool、int32、float、string、enum、message
- modifier:
- required:require修饰的字段值必须设置,否则在反序列话时会遇到RuntimeException,序列化这样的数据也会遇到IOException。
- optional:optional修饰的字段值可有可无,对于简单数据类型,可以设置默认值。否则,系统自己设置默认值:数字类型为0,字符类型为空字符串,布尔值为false,
- repeated:repeated修饰的字段值可能有0个或多个,并且protobuf保留了这些值的顺序
- “=1, =2”:每个字段都有类似这样的指定,这个是用于标记每个元素在二进制编码中的标识。1-15比更多的数字可以少用一个byte,所以在优化的时候,可以给那些公共使用或者重复的字段指定1-15。
编译Protocol Buffer
在命令行使用protoc命令可以生成类来读写地址本,在命令行里执行protoc -I=$SRC_DIR --java_out=$DST_DIR $SRC_DIR/addressbook.proto
,生成的com/example/tutorial/AddressBookProtos.java在指定的路径下。protoc的命令行用法如下所示:
Usage: protoc [OPTION] PROTO_FILES
Parse PROTO_FILES and generate output based on the options given:
-IPATH, --proto_path=PATH Specify the directory in which to search for
imports. May be specified multiple times;
directories will be searched in order. If not
given, the current