protobuf的编译,官方文档建议使用maven,因此如果没有maven先安装maven.
windows下可能会只配置了IDE的java环境.如果想用CMD来编译protobuf的话,需要在windows环境变量中配置JAVA_HOME.
安装
安装maven
http://maven.apache.org/download.cgi 下载最新maven
解压到喜欢的英文目录,配置环境变量:
在path中加入maven路径.
在cmd中用mvn -v测试
安装protobuf
在GitHub上下载 https://github.com/google/protobuf/releases , windows下需要下载java和win32.这里下载的3.5.0版本.
解压:
protobuf-java-3.5.0
protoc-3.5.0-win32
编译protobuf
将protoc-3.5.0-win32中的exe文件复制到protobuf-java-3.5.0目录下的scr\下
打开CMD进入protobuf-java-3.5.0/java/ 执行命令:
- 1
编译成功得到如下信息
生成的包在个文件夹中的target中,例如我这里是在protobuf-java-3.5.0/java/core/target中
如果采用maven项目的话可以不编译jar包,而加入如下信息
<dependency> <groupId>com.google.protobuf</groupId> <artifactId>protobuf-java</artifactId> <version>3.5.0</version> </dependency>
1
Java使用protobuf
定义数据结构
定义protobuf的数据结构,这里要写一个.proto文件。这个文件有点类似于定义一个类。
具体参照protobuf官方文档.
protoc.exe生成java文件
若要生成java文件,需要在proto文件开头加入
- 例:
-
syntax = "proto2";//指定版本信息,不指定会报错 package infopack; //package声明符 message info //message为关键字,作用为定义一种消息类型 { string addr = 1; //地址 string group = 2; //分组 }
导入定义(import)
如果需要需要生成的对象包含其他自定义对象,则需要定义多个proto,使用import引入addressbook.proto文件内容如下,addressbook.proto文件需要导入info.proto文件的内容:
syntax = "proto2";//指定版本信息,不指定会报错 import "info.proto"; //导入定义 package tutorial; //package声明符 message Person //message为关键字,作用为定义一种消息类型 { string name = 1; //姓名 int32 id = 2; //id string email = 3; //邮件 enum PhoneType //枚举消息类型 { MOBILE = 0; //proto3版本中,首成员必须为0,成员不应有相同的值 HOME = 1; WORK = 2; } message PhoneNumber { string number = 1; PhoneType type = 2; } repeated PhoneNumber phones = 4; //phones为数组 //info定义在"info.proto" //类型格式:包名.信息名 infopack.info tmp = 5; } message AddressBook { repeated Person people = 1; }
命令行运行:
- 1
输出文件夹是E:\java,输入是Immortaldb.proto
得到Immortaldb.java
将得到的java拷入工程,工程需要依赖之前得到的jar文件
序列化与反序列化
以Player为例
序列化,通过该类型的Builder的build方法来构建一个对象.再序列化对象
//Player序列化 public byte[] serializePlayer() throws IOException{ byte[] byteArray = null; Immortaldb.Player.Builder playerBuilder= Immortaldb.Player.newBuilder(); //这里应该有Player各项的赋值 playerBuilder.setRoleid(12345); …… Immortaldb.Player player = playerBuilder.build(); // 将数据写到输出流,如网络输出流,这里用ByteArrayOutputStream来模拟 ByteArrayOutputStream output = new ByteArrayOutputStream(); player.writeTo(output); byteArray = output.toByteArray(); return byteArray; }
- 2
反序列化:
//Player反序列化 public void decodePlayer(byte[] serial) throws InvalidProtocolBufferException { Immortaldb.Player player= Immortaldb.Player.parseFrom(serial); // 这里取Player的各个项 long roleId = player.getRoleId(); …… }
发表吐槽
你肿么看?
既然没有吐槽,那就赶紧抢沙发吧!