打卡日期(2019-07-09)
学习要点
- 1.Protobuf 基本属性
- 2.Protobuf optimize_for文件级别优化
1.Protobuf 基本属性
首先需要手动编写一个.proto文件,定义我们程序中需要的数据结构,在protobuf术语中,结构话数据被称为message,proto文件非常类似于java 或者 C++ 的数据定义。 Message可以嵌套使用
2.Protobuf optimize_for文件级别优化
- SPEED:表示生成代码运行效率高,但是由此生成代码编译后会占用跟多空间
- CODE_SIZE:与SPEED正好相反,代码运行效率低,但是由此编译之后生成的文件会占用更少的空间,通常用于phone
- LITE_RUNTIME:生成的代码效率高,同时编译后的文件占用的空间少。这是以牺牲Protobuf Buffer提供的反射功能为代价的。
syntax = "proto2";
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 phones = 4;
}
message AddressBook {
repeated Person people = 1;
}
package
- package:对应java的namespace
- java_package:如果没有定义java_package,默认的包名使用package,如果定义了java_package,则使用java_package定义的包
- java_outer_classname:在.proto文件中,所有的都属于java_outer_classname类文件的子类。
标注
- require:表示该属性为必选属性,否则对应message初始化的时候回抛出RuntimeException运行时异常。
在解析未初始化的message时候,会抛出IOException
- optional:表示该属性为可选属性,不指定的时候使用其默认值(int或char 默认0,string默认空字符串..)
- repeated:表示该属性为重复字段,可以看做是动态数组
在使用protobuf的时候,标注尽量使用optional,require的弊大于利,所以不建议使用。
引入protobuf相关依赖
compile (
//protobuf依赖
"com.google.protobuf:protobuf-java:3.8.0",
"com.google.protobuf:protobuf-java-util:3.8.0"
)
自己手动写一个proto文件,并用protoc编译成java文件
//proto2版本
syntax = "proto2";
//定义包名
package protobuf;
//- SPEED:表示生成代码运行效率高,但是由此生成代码编译后会占用跟多空间
//- CODE_SIZE:与SPEED正好相反,代码运行效率低,但是由此编译之后生成的文件会占用更少的空间,通常用于phone
//- LITE_RUNTIME:生成的代码效率高,同时编译后的文件占用的空间少。这是以牺牲Protobuf Buffer提供的反射功能为代价的。
option optimize_for = SPEED;
option java_package = "com.dragon.protobuf";
option java_outer_classname = "Person";
message Student{
optional string name = 1;
optional int32 age = 2;
optional string address = 3;
}
运行命令:
E:\tools\gradle\netty01>protoc --java_out=src/main/java src/main/protobuf/Student.proto
生成Person.java类
注:maven中添加的protobuf依赖一定要比安装的环境变量的版本高,不然生成的java文件会报错
编写测试类ProtobufTest
package com.dragon.protobuf;
import com.google.protobuf.InvalidProtocolBufferException;
/**
* @Description:
*/
public class ProtobufTest {
public static void main(String[] args) throws InvalidProtocolBufferException {
Person.Student student = Person.Student
// newBuilder 新建一个builder对象
.newBuilder()
.setName("张三")
.setAddress("北京市西城区长安街")
.setAge(20)
// 将builder对象转化成object对象,如果require没有设置值,直接抛出异常
.build();
// 序列化过程,将对象转化成二进制数组,方便网络传输和存储
byte[] personByte = student.toByteArray();
// 反序列化过程,支持跨平台、跨语言
Person.Student student1 = Person.Student.parseFrom(personByte);
System.out.println(student1.getName());
System.out.println(student1.getAddress());
System.out.println(student1.getAge());
}
}
运行main方法:
张三
北京市西城区长安街
20