Google Protocol Buffers快速入门指南

news/2024/10/11 10:36:36/

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

概念

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()方法。

java">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 读取并解析消息

其所对应的使用示例为:

java">// 序列化为字节数组
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();
}

结语

参考资料

  • Protocol Buffers Documentation

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


http://www.ppmy.cn/news/1533126.html

相关文章

HarmonyOS Next应用开发——自定义组件的使用

自定义组件的使用 在ArkUI中&#xff0c;UI显示的内容均为组件&#xff0c;由框架直接提供的称为系统组件&#xff0c;由开发者定义的称为自定义组件。在进行 UI 界面开发时&#xff0c;通常不是简单的将系统组件进行组合使用&#xff0c;而是需要考虑代码可复用性、业务逻辑与…

一个很好的例子说明均值平滑滤波器有旁瓣泄漏效应

禹晶、肖创柏、廖庆敏《数字图像处理&#xff08;面向新工科的电工电子信息基础课程系列教材&#xff09;》P89

大数据毕业设计选题推荐-国潮男装微博评论数据分析系统-Hive-Hadoop-Spark

✨作者主页&#xff1a;IT研究室✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Python…

代码整洁之道 — 2 函数规范

目录 1 简短 2 switch语句 3 函数参数 4 无副作用 5 结构化编程 1 简短 函数应该保持简短&#xff0c;以提高代码的可读性和可维护性。简短的函数通常在20行以内&#xff0c;并且每个函数只做一件事&#xff0c;并清晰地表达其目的。函数应该保持单一职责&#xff0c;只处…

第1 章 第一节:基础语法

第1 章 第一节&#xff1a;基础语法 1.1书写规则 1.1.1关键字 在Java语言中&#xff0c;已经定义好的&#xff0c;具有一定的功能和作用的英文单词。所有的关键字都是小写的 在Java中总共有51个关键字&#xff0c;还有两个保留字const\goto. 常见的关键字&#xff1a; if…

华为设备所有查看命令以及其对应作用

display interface&#xff1a;查看接口的状态、配置和统计信息。display ip interface brief&#xff1a;简要查看接口的 IP 地址信息。display ip routing-table&#xff1a;查看路由表信息。display ospf peer&#xff1a;查看 OSPF 邻居的状态。display ospf routing&#…

快速选择算法--无序数组中寻找中位数 O(n)的算法及证明

一、排序算法 排序的算法是最容易想到的&#xff0c;但是即使是快排&#xff0c;平均复杂度也只有 O ( n log ⁡ n ) O(n \log n) O(nlogn)。 #include <iostream> #include <vector> #include <algorithm> using namespace std;double findMid(vector<…

【吊打面试官系列-MySQL面试题】为表中得字段选择合适得数据类型

大家好&#xff0c;我是锋哥。今天分享关于【为表中得字段选择合适得数据类型】面试题&#xff0c;希望对大家有帮助&#xff1b; 为表中得字段选择合适得数据类型 字段类型优先级: 整形>date,time>enum,char>varchar>blob,text 优先考虑数字类型&#xff0c;其次是…