Google Protocol Buffers快速入门指南

声明:未经作者允许,禁止转载。

概念

Portocol Buffer是谷歌提出来的一种序列化结构数据的机制,它的可扩展性特别强,支持C++、C#、Java、Go和Python等主流编程语言。使用Portocol Buffer时,仅需要定义好数据的结构化方式,然后就可以使用编译生成的源代码在各种语言各种数据流中写入和读取该结构化数据。

Protocol Buffer的安装

打开Protocol Buffer的Github地址,选择适合自己系统的版本。例如对于windows系统,可以下载protoc-28.2-win64.zip,并放置于合适的位置,之后进入bin目录,可以看到protoc.exe,将其所在的目录到环境变量中。

然后打开命令行,输入protoc,若看到如下界面说明安装成功。

protoc-command

使用Protocol Buffer

本节主要介绍Portocol Buffer关于Java的使用案例,其步骤大致为:

  • .proto文件中定义消息格式;
  • 使用Protocol buffer编译器编译.proto文件;
  • 使用Java API进行消息的读写。

消息的定义

对于要序列化的数据结构,需要在.proto文件中定义相应的消息格式。

syntax = "proto3"; // 使用proto3语法

option java_package = "com.test.protobuf";
option java_outer_classname = "PersonBuf";

message Person{
  string name = 1;
  int32 age = 2;
  string id = 3;
}

.proto文件中支持类似C/C++中的///*...*/两种注释。

字段说明

在定义域(字段)时,必须为每个定义的字段分配一个在 [ 1 , 536 , 870 , 911 ] [1,536,870,911] [1,536,870,911]的数字,但需要注意的是:

  • 消息中不同字段分配的数字必须唯一;
  • 数字范围 [ 19 , 000 , 19 , 999 ] [19,000, 19,999] [19,000,19,999]是Protocol Buffer预留的,使用该范围内的保留字段编号会报错;

标量类型

.proto支持的常用标量类型包括:

.proto类型C++类型Java类型
doubledoubledouble
floatfloatfloat
int32int32int
int64int64long
boolboolboolean
stringstringString

可选项

.proto文件中一些常用的可选项包括:

  • java_package:常用于Java 或 Kotlin代码,用于指定生成的Java类的包名,帮助组织代码;
  • java_outer_classname:指定生成的外部类的名称。默认情况下,Protobuf会根据文件名生成外部类名;
  • java_multiple_files:控制是否为每个消息生成独立的Java文件。如果设置为true,每个消息会被生成到单独的文件中。

编译.Proto文件

当编译.proto文件时,编译器会生成你所选择的语言的代码。生成的代码将被用于处理自定义的消息类型,包括获取和设置字段值、序列化和反序列化。

以Java语言为例,编译器为每种消息类型生成一个 .java 文件,并为创建消息类实例提供了一个特殊的 Builder 类。

protoc --java_out=DST_DIR Person.proto

--java_out用于指定生成的Java文件的输出目录

Java程序中应用

在使用需要在pom.xml中添加Protobuf相关的依赖:

<dependency>
    <groupId>com.google.protobuf</groupId>
    <artifactId>protobuf-java</artifactId>
    <version>4.28.2</version>
</dependency>

若要构造消息,首先需要构造一个builder,并设置想要设置的任何字段为自定义的值,然后调用构造器的build()方法。

PersonBuf.Person person = PersonBuf.Person.newBuilder()
                            .setName("Java")
                            .setId("1001")
                            .setAge(18)
                            .build();
System.out.println(person.isInitialized()); // 检查是否已设置所有必填字段
System.out.println(person.toString()); // 返回字符串格式的消息

解析和序列化

Protobuf关于解析和序列化的方法包括:

方法说明
byte[] toByteArray()序列化消息并返回字节数组
static Person parseFrom(byte[] data)从给定的字节数组解析消息
void writeTo(OutputStream output)序列化消息并将其写入OutputStream
static Person parseFrom(InputStream input)InputStream 读取并解析消息

其所对应的使用示例为:

// 序列化为字节数组
byte[] bytes = person.toByteArray();
PersonBuf.Person person1 = PersonBuf.Person.parseFrom(bytes);
System.out.println(person1.toString());

// 序列化并保存
String filename = "src/main/files/Person.bin";
try(FileOutputStream outputStream = new FileOutputStream(filename)){
    person.writeTo(outputStream);
}catch (IOException e){
    e.printStackTrace();
}

// 反序列化读取构造实例
try(FileInputStream inputStream = new FileInputStream(filename)){
    PersonBuf.Person person2 = PersonBuf.Person.parseFrom(inputStream);
    System.out.println(person2.toString());
}catch (IOException e){
    e.printStackTrace();
}

结语

参考资料

以上便是本文的全部内容,若是觉得不错的话可以支持一下,你们的支持是博主继续更新的不竭动力。若发现任何错误,也敬请批评指正!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

斯曦巍峨

码文不易,有条件的可以支持一下

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值