Protocol Buffers
(简称为ProtoBuf
)是一种用于序列化、结构化数据的语言无关、平台无关、可扩展的机制。它由Google
开发并于2008年开源发布。
Protocol Buffers
通过使用结构化的消息定义文件(.proto
文件)来描述数据结构,然后利用特定的编译器将这些消息定义文件编译成相应编程语言的类。这些生成的类提供了一组API,用于在不同的平台和编程语言之间进行数据的序列化、传输和反序列化操作。
Protobuf
支持生成代码的语言包括Java
、Python
、C++
、Go
、Ruby
、C#
。
官网地址:https://developers.google.com/protocol-buffers/。
官方开源地址 :https://github.com/protocolbuffers/protobuf。
语法指南:https://developers.google.com/protocol-buffers/docs/proto。
Portobuf
的序列化的结果体积要比XML
、JSON小
很多,XML
和JSON
的描述信息比较多,而且是文本存储格式,导致消息要大;Portobuf
的存储格式是二进制。此外Portobuf
还使用了Varint 编码,减少数据对空间的占用。
Portobuf
序列化和反序列化速度比XML
、JSON
快很多,是直接把对象和字节数组做转换,而XML
和JSON
还需要构建成XML
或者JSON
对象结构。
但是Portobuf
自解耦性差,以二进制数据流方式存储(不可读),需要通过.proto
文件才能了解到数据结构。
使用ProtoBuf
,首先需要通过ProtoBuf
语法定义数据结构(消息),这些定义好的数据结构保存在.proto
为后缀的文件中。
server.proto
// 指定protobuf的版本,proto3是最新的语法版本
syntax = "proto3";
// 定义数据结构message
message Server{
string host = 1; // 定义一个string类型的字段,字段名字为host, 序号为1
int32 code = 2; // 定义一个int32类型的字段,字段名字为code , 序号为2
}
proto文件中,字段后面的序号,不能重复,定义了就不能修改,可以理解成字段的唯一ID。
Protobuf
的github
发布地址:https://github.com/protocolbuffers/protobuf/releases
Protobuf
的编译器叫protoc
,在上面的网址中找到最新版本的安装包,下载安装。
这里下载的是:protoc-23.2-win64.zip
,下载后,解压到你想要的安装目录即可。
可以把protoc下的bin目录路径添加到环境变量,否则要输入全部bin目录写命令操作。
protoc编译器支持将proto文件编译成多种语言版本的代码,这里以java为例。
切换到proto文件所在的目录, 执行下面命令
protoc --java_out=. server.proto
然后在当前目录生成了一个Server.java
的java
类文件,这个就是我们刚才用protobuf
语法定义的数据结构对应的java
类文件,通过这个类文件我们就可以操作定义的数据结构。
引入pom依赖
<dependency>
<groupId>com.google.protobufgroupId>
<artifactId>protobuf-javaartifactId>
<version>3.6.1version>
dependency>
设置build代码
<build>
<extensions>
<extension>
<groupId>kr.motd.mavengroupId>
<artifactId>os-maven-pluginartifactId>
<version>1.5.0.Finalversion>
extension>
extensions>
<plugins>
<plugin>
<groupId>org.xolstice.maven.pluginsgroupId>
<artifactId>protobuf-maven-pluginartifactId>
<version>0.5.0version>
<configuration>
<protocArtifact>com.google.protobuf:protoc:3.6.1:exe:${os.detected.classifier}protocArtifact>
<pluginId>grpc-javapluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:1.14.0:exe:${os.detected.classifier}pluginArtifact>
configuration>
<executions>
<execution>
<goals>
<goal>compilegoal>
<goal>compile-customgoal>
goals>
execution>
executions>
plugin>
plugins>
build>
配置好以后,将对应的proto
文件放到新创建的proto
文件下,在maven
中执行compile/protobuf
就可以,在target
中我们可以找到对应的pb文件。
记得导入protobuf基础类库:
<dependency>
<groupId>com.google.protobufgroupId>
<artifactId>protobuf-javaartifactId>
<version>3.9.1version>
dependency>
Protocol Buffers
把生成的Server
类复制到当前目录,然后写个demo
:
Server.Response.Builder builder = Server.Response.newBuilder();
// 设置字段值
builder.setHost("localhost");
builder.setCode(200);
Server.Response response = builder.build();
// 将数据根据protobuf格式,转化为字节数组
byte[] byteArray = response.toByteArray();
// 反序列化,二进制数据
try {
Server.Response newResponse = Server.Response.parseFrom(byteArray);
System.out.println(newResponse.getHost());
System.out.println(newResponse.getCode());
} catch (Exception e) {
}
使用ProtoBuf
,首先需要通过ProtoBuf
语法定义数据结构(消息),这些定义好的数据结构保存在.proto
为后缀的文件中。
server.proto
// 指定protobuf的版本,proto3是最新的语法版本
syntax = "proto3";
// 定义数据结构message
message Server{
string host = 1; // 定义一个string类型的字段,字段名字为host, 序号为1
int32 code = 2; // 定义一个int32类型的字段,字段名字为code , 序号为2
}
proto文件中,字段后面的序号,不能重复,定义了就不能修改,可以理解成字段的唯一ID。
Protobuf
的github
发布地址:https://github.com/protocolbuffers/protobuf/releases
Protobuf
的编译器叫protoc
,在上面的网址中找到最新版本的安装包,下载安装。
这里下载的是:protoc-23.2-win64.zip
,下载后,解压到你想要的安装目录即可。
可以把protoc下的bin目录路径添加到环境变量,否则要输入全部bin目录写命令操作。
protoc编译器支持将proto文件编译成多种语言版本的代码,这里以java为例。
切换到proto文件所在的目录, 执行下面命令
protoc --python_out=. server.proto
然后在当前目录生成了一个server_pb2.py
的python
文件,这个就是我们刚才用protobuf
语法定义的数据结构对应的python
文件,通过这个文件我们就可以操作定义的数据结构。
记得把server.proto
、server_pb2.py
放入一个目录下,然后写python
代码访问Server
:
import server_pb2 # 导入生成的Python文件
from google.protobuf import json_format # 导入protobuf的JSON格式转换库(可选)
# 创建一个新的消息对象
message = server_pb2.Response()
# 设置字段值
message.host = "172.0.0.1"
message.code = 100
# 将消息序列化为字节串
serialized_data = message.SerializeToString()
# 将字节串反序列化为消息
deserialized_message = server_pb2.Response()
deserialized_message.ParseFromString(serialized_data)
# 将消息对象转换为JSON字符串
json_string = json_format.MessageToJson(message)
# 将JSON字符串转换为消息对象
json_message = server_pb2.Response()
print(json_format.Parse(json_string, json_message))
参考下一篇:点击查看