typora-copy-images-to: assets
typora-root-url: assets
Protocol Buffers
Protocol Buffers介绍
- Protocal Buffers(简称protobuf)是谷歌的一项技术,用于结构化的数据序列化、反序列化,常用于RPC 系统和持续数据存储系统。
- 其类似于XML生成和解析,但protobuf的效率高于XML,不过protobuf生成的是字节码,可读性比XML差,类似的还有json、Java的Serializable等。
- 很适合做数据存储或 RPC 数据交换格式。可用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。
- 参考:https://zhuanlan.zhihu.com/p/53339153
Idea 安装protobuf插件
安装插件protobuf Support,之后重启
- 找到资料包中的protobuf-jetbrains-plugin-0.13.0.zip,在IDEA中安装插件即可
使用ProtoBuf序列化数据
配置Maven依赖与插件
<dependencies>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>3.4.0</version>
</dependency>
</dependencies>
<build>
<extensions>
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.6.2</version>
</extension>
</extensions>
<plugins>
<!-- Protobuf插件 src/main/java/proto -->
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.5.0</version>
<configuration>
<protoSourceRoot>${project.basedir}/src/main/java/proto</protoSourceRoot>
<protocArtifact>
com.google.protobuf:protoc:3.1.0:exe:${os.detected.classifier}
</protocArtifact>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
编写 proto 文件
-
protobuf3的语法参考讲义中的「 protobuf3 语法」
-
在main文件夹下,创建 proto 目录,并编写proto文件
syntax = "proto3";
option java_package = "com.wangjie.protobuf";
option java_outer_classname = "Msg";
message User {
int32 id = 1;
string name = 2;
string sex = 3;
}
message Stats{
int32 hp =1;
int32 mp = 2;
int32 exp =3;
int32 atk =4;
int32 def =5;
}
注意:classname不能与message name一样
protobuf与java类型对照表
.proto Type | Java Type | 备注 |
---|---|---|
double | double | |
float | float | |
int32 | int | 使用可变长度编码。负数编码效率低下–如果您的字段可能具有负值,请改用sint32。 |
int64 | long | 使用可变长度编码。负数编码效率低下–如果您的字段可能具有负值,请改用sint64。 |
uint32 | int | 使用可变长度编码。 |
uint64 | long | 使用可变长度编码。 |
sint32 | int | 使用可变长度编码。有符号的int值。与常规int32相比,它们更有效地编码负数。 |
sint64 | long | 使用可变长度编码。有符号的int值。与常规int64相比,它们更有效地编码负数。 |
fixed32 | int | 始终为四个字节。如果值通常大于2^28,则比uint32更有效。 |
fixed64 | long | 始终为八个字节。如果值通常大于2^56,则比uint64更有效。 |
sfixed32 | int | 始终为四个字节。 |
sfixed64 | long | 始终为八个字节。 |
bool | boolean | |
string | String | 字符串必须始终包含UTF-8编码或7位ASCII文本。 |
bytes | ByteString | 可以包含任意字节序列。 |
执行protobuf:compile编译命令
- 将 proto 文件编译成java代码
编写代码使用ProtoBuf序列化、反序列化
package com.wangjie.protobuf;
import com.google.protobuf.InvalidProtocolBufferException;
public class ProtoBufMsg {
public static void main(String[] args) {
Msg.User.Builder builder = Msg.User.newBuilder();
builder.setId(1);
builder.setName("saber");
builder.setSex("female");
byte[] bytes = builder.build().toByteArray();
System.out.println("--protobuf---");
for (byte b : bytes) {
System.out.print(b);
}
System.out.println();
System.out.println("---");
try {
Msg.User user = Msg.User.parseFrom(bytes);
System.out.println(user);
} catch (InvalidProtocolBufferException e) {
e.printStackTrace();
}
Msg.Stats.Builder statsBuild = Msg.Stats.newBuilder();
statsBuild.setHp(10);
statsBuild.setMp(10);
statsBuild.setExp(10);
statsBuild.setDef(10);
statsBuild.setAtk(10);
byte[] bytes1 = statsBuild.build().toByteArray();
System.out.println("--protobuf---");
for (byte b : bytes1) {
System.out.print(b);
}
System.out.println();
System.out.println("---");
Msg.Stats stats = null;
try {
stats = Msg.Stats.parseFrom(bytes1);
} catch (InvalidProtocolBufferException e) {
e.printStackTrace();
}
System.out.println(stats);
}
}