Protobuf 简介

article/2025/11/6 18:41:52

protobuf (protocol buffer) 是谷歌内部的混合语言数据标准。通过将结构化的数据进行序列化(串行化),用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。通常说的protobuf包括以下三点:

  • 是一种二进制数据交换格式。支持不同与语言例如C++、java中定义的存储类的内容与二进制序列串相互转换,主要用于数据传输或保存。
  • 定义了一种源文件,扩展名为.proto.使用此文件,可以定义存储类的内容。
  • 可以使用编译器将.proto编译成.cc 或.java,使之成为一个可以在C++或java等工程中直接使用的类。

定义Proto文件

messageprotobuf中定义一个消息类型是通过关键字message字段指定的,这个关键字类似于C++/Java中的class关键字。使用protobuf编译器将proto编译成C++代码之后,每个message都会生成一个名字与之对应的C++类,该类公开继承自google::protobuf::Message

创建turorial.person.proto 文件,文件内容如下:

// FileName: tutorial.person.proto

// 通常文件名建议命名格式为 包名.消息名.proto

// 表示正在使用proto2命令

syntax = "proto2";

//包声明,tutorial 也可以声明为二级类型。

//例如a.b,表示a类别下b子类别

package tutorial;

//编译器将生成一个名为person的类

//类的字段信息包括姓名name,编号id,邮箱email,

//以及电话号码phones

message Person {

  required string name = 1;  // (位置1)

  required int32 id = 2; 

  optional string email = 3;  // (位置2)

  enum PhoneType {  //电话类型枚举值

    MOBILE = 0;  //手机号 

    HOME = 1;    //家庭联系电话

    WORK = 2;    //工作联系电话

  }

 

  //电话号码phone消息体

  //组成包括号码number、电话类型 type

  message PhoneNumber {

    required string number = 1;   

    optional PhoneType type =

          2 [default = HOME]; // (位置3)

  } 

 

  repeated PhoneNumber phones = 4; // (位置4)

}

// 通讯录消息体,包括一个Person类的people

message AddressBook {

  repeated Person people = 1;

}

字段解释:

包声明

proto 文件以package声明开头,这有助于防止不同项目之间命名冲突。在C++中,以package声明的文件内容生成的类将放在与包名匹配的namespace中,上面的.proto文件中所有的声明都属于tutorial

标识符:

protobuf协议的标识符为message或enum,如示例中的Person和PhoneType。message标识一条消息,enum标识一个枚举类型。使用protobuf编译器将协议文件编译后,message和enum都会生成一个类

字段规则

·  repeated: 消息体中可重复字段,重复的值的顺序会被保留(例如位置3)。其中,proto3默认使用packed方式存储,这样编码方式比较节省内存。

标识号

标识号:在消息体的定义中,每个字段都必须要有一个唯一的标识号,标识号是[0,2^29-1]范围内的一个整数。以Person为例,name=1,id=2, email=3, phones=4 中的1-4就是标识号。

数据定义

许多标准的简单数据类型都可以用作message字段类型,包括bool,int32,float,doublestring。还可以使用其他message类型作为字段类型在消息体中添加更多结构。在上面的示例中,Person包含PhoneNumber message, 而AddressBook包含Person message。甚至可以定义嵌套在其他message中的message类型。例如,上面的PhoneNumber定义在Person

 

在java中使用protobuf的简单示例

以下是示例中用到的proto文件teacher.proto:

syntax = "proto3";

package space;

message course{

   // 课程名称

   string name = 1;

   // 课程分数

   int32 score = 2;

}

message student{

// 学生名称

  string name = 1;

   // 学生年龄

   int32 age = 2;

   // 学生所修课程,可能是多门,是一组数组

   repeated course course = 3;

  }

从Release Protocol Buffers v3.5.1 · protocolbuffers/protobuf · GitHub 下载protoc工具,此工具可以根据proto文件生成java类。

下载完成后,解压缩该文件。

打开cmd命令窗口,跳转至解压缩路径:

执行以下命令:

protoc.exe --java_out=src/main/java/ teacher.proto

执行此命令前,需要在新建文件夹目录src/main/java

执行成功后,可以看到在src/main/java 下生成的java类文件Teacher.java。

新建一个maven工程,并导入以下pom依赖

    <dependency>

        <groupId>com.google.protobuf</groupId>

        <artifactId>protobuf-java</artifactId>

        <version>3.21.9</version>

    </dependency>

    <!-- https://mvnrepository.com/artifact/com.google.protobuf/protobuf-java-util -->

    <dependency>

        <groupId>com.google.protobuf</groupId>

        <artifactId>protobuf-java-util</artifactId>

        <version>3.21.9</version>

    </dependency>

    <!-- https://mvnrepository.com/artifact/io.grpc/grpc-all -->

    <dependency>

        <groupId>io.grpc</groupId>

        <artifactId>grpc-all</artifactId>

        <version>1.11.0</version>

    </dependency>

</dependencies>

<build>

    <extensions>

        <extension>

            <groupId>kr.motd.maven</groupId>

            <artifactId>os-maven-plugin</artifactId>

            <version>1.5.0.Final</version>

        </extension>

    </extensions>

    <plugins>

        <plugin>

            <groupId>org.xolstice.maven.plugins</groupId>

            <artifactId>protobuf-maven-plugin</artifactId>

            <version>0.5.0</version>

            <configuration>

                <protocArtifact>

                    com.google.protobuf:protoc:3.1.0:exe:${os.detected.classifier}

                </protocArtifact>

                <pluginId>grpc-java</pluginId>

                <pluginArtifact>

                    io.grpc:protoc-gen-grpc-java:1.11.0:exe:${os.detected.classifier}

                </pluginArtifact>

            </configuration>

            <executions>

                <execution>

                    <goals>

                        <goal>compile</goal>

                        <goal>compile-custom</goal>

                    </goals>

                </execution>

            </executions>

        </plugin>

    </plugins>

</build>

将Teacher.java 添加至该工程。新建一个测试类TestMyProtobuf.java 进行测试。代码如下:

import com.google.protobuf.InvalidProtocolBufferException;

import com.google.protobuf.util.JsonFormat;

import space.Teacher;

import java.util.Arrays;

public class TestMyProtobuf {

    public static void main(String[] args) {

        // 生成课程1对象

        Teacher.course.Builder courseBuilder1 = Teacher.course.newBuilder();

        courseBuilder1.setName("Java");

        courseBuilder1.setScore(99);

        Teacher.course course1 = courseBuilder1.build();

        // 生成课程2对象

        Teacher.course.Builder courseBuilder2 = Teacher.course.newBuilder();

        courseBuilder2.setName("Python");

        courseBuilder2.setScore(98);

        Teacher.course course2 = courseBuilder2.build();

        // 生成学生对象

        Teacher.student.Builder studentBuilder = Teacher.student.newBuilder();

        studentBuilder.setName("Lucy");

        studentBuilder.setAge(23);

        studentBuilder.addCourse(0,course1);

        studentBuilder.addCourse(1,course2);

        Teacher.student student = studentBuilder.build();

        // proto对象

        System.out.println("The student object is: \n" + student);

        // 序列化

        byte[] studentByte = student.toByteArray();

        System.out.println("The student after encode is:\n" + Arrays.toString(studentByte));

        try {

            // 反序列化

            Teacher.student newStudent = Teacher.student.parseFrom(studentByte);

            System.out.println("The student after decode is:\n" + newStudent);

            // 转换json

            System.out.println("The student json format is:\n" + JsonFormat.printer().print(student));

        } catch (InvalidProtocolBufferException e) {

            e.printStackTrace();

        }

    }

}

测试结果如下:

The student object is:

name: "Lucy"

age: 23

course {

  name: "Java"

  score: 99

}

course {

  name: "Python"

  score: 98

}

The student after encode is:

[10, 4, 76, 117, 99, 121, 16, 23, 26, 8, 10, 4, 74, 97, 118, 97, 16, 99, 26, 10, 10, 6, 80, 121, 116, 104, 111, 110, 16, 98]

The student after decode is:

name: "Lucy"

age: 23

course {

  name: "Java"

  score: 99

}

course {

  name: "Python"

  score: 98

}

The student json format is:

{

  "name": "Lucy",

  "age": 23,

  "course": [{

    "name": "Java",

    "score": 99

  }, {

    "name": "Python",

    "score": 98

  }]

}

 


http://chatgpt.dhexx.cn/article/0Ooif3SM.shtml

相关文章

【prony】基于prony算法的参数辨识matlab仿真

1.软件版本 matlab2013b 2.系统概述 建立如下被测信号: 被测信号中包含四个振荡模态,在数据窗宽度同样为10s的前提下,利用不同的采样频率做普罗尼计算。结果如表1所示。根据公式的基本表达式: 所以最后,进行估计得到的参数为:

ADI Blackfin DSP处理器-BF533的开发详解54:CVBS输出-DSP和CH7024的应用详解(含源码)

硬件准备 ADSP-EDU-BF533&#xff1a;BF533开发板 AD-HP530ICE&#xff1a;ADI DSP仿真器 软件准备 Visual DSP软件 硬件链接 CVBS OUT 视频输出 硬件实现原理 CVBS_OUT 子卡板连接在 ADSP-EDU-BF53x 开发板的扩展端口 PORT3 和 PORT4 上&#xff0c;板卡插入时&#xff0…

【AI+】Martin Fowler: 基于 AI 辅助的测试驱动开发的技术 | An example of LLM prompting for programming

Martin Fowler: 基于 AI 辅助的测试驱动开发的技术 | An example of LLM prompting for programming 目录 Martin Fowler: 基于

iPhone 13分辨率,屏幕尺寸,PPI 详细数据对比 iPhone 13 Pro、iPhone 13 Pro Max、iPhone 13 mini

点击图片放大查看 iPhone 14分辨率,屏幕尺寸,PPI 详细数据对比 iPhone 14 Plus、iPhone 14 Pro、iPhone 14 Pro Max​​​​​​​

android 主流分辨率是多少,android 屏幕分辨率问题

iPhone的icon设计就这么简单&#xff0c;iPhone的屏幕只有320480像素&#xff0c;所以程序没有适配性问题。 Android 在研究Android的icon设计之前&#xff0c;有必要先了解Android的界面是如何适配多样化屏幕的。 适配性 由于同一个UI元素(如100100像素的图片)在高精度的屏幕上…

iPhone手机屏幕大小及分辨率

以前一直找,现在自己保存起来

IPHONE屏幕大小,分辨率解析

相关概念 // 竖屏时,返回的是不带有状态栏的Rect.横屏时,返回整个屏幕Rect [UIScreen mainScreen].applicationFrame);//The natural scale factor associated with the screen(自然比例因子) [UIScreen mainScreen].scale);//The native scale factor for the physical scree…

iPhone 各屏幕尺寸及解析

一.iPhone 各屏幕尺寸表 手机型号屏幕尺寸(inch)像素密度&#xff08;PPI&#xff09;逻辑分辨率 &#xff08;point&#xff09;物理分辨率&#xff08;屏幕分辨率&#xff09;&#xff08;pixel&#xff09;缩放因子&#xff08;scale factor&#xff09;宽高比&#xff08;…

各版本iPhone屏幕分辨率尺寸图标

1、3.5&#xff08;iPhone 4、iPhone 4s&#xff09;&#xff1a; 640x960 2、4.0&#xff08;iPhone 5、iPhone 5s、iPhone 5C、iPhone SE&#xff09;&#xff1a; 640x1136 3、4.7&#xff08;iPhone 6、iPhone 6s、iPhone 7、iPhone 8&#xff09;&#xff1a; 750x1334&…

各型号iPhone的屏幕参数 逻辑分辨率 物理分辨率 - iOS Device Display Summary - 更新到iPhone 13系列

详询&#xff1a; iOS设备分辨率 - 逻辑分辨率 - 屏幕参数 - iPhone/iPad/iWatch without Macbookhttps://tools.rudon.cn/electronics/resolution/ios/

EditPlus中文版 安装教程

EditPlus中文版安装教程 1、下载软件压缩包,解压即可。不需要安装,解压后打开“EditPlus中文版”文件夹(软件我会打包好,在文中的最低端找到即可下载;若链接失效了,请告知我一声,我会重新更新链接) 2.打开EditPlus.exe启动软件。 3、设置程序的配置文件目录。 …

安装Editplus软件

1.安装Editplus软件 百度云网盘链接:https://pan.baidu.com/s/1alKZWD_yXUO4be6wUoM5Fg?pwdhykz 提取码:hykz 2.点开下载的软件进行安装&#xff0c;Accept下一步 3.选择自己想要安装的文件目录 4.点击Start Copy进行下一步安装&#xff0c;安装完成后桌面会有Editplus的软件…

EditPlus 5.0.651 中文版

各位网友&#xff1a;4.0 版本以前的注册码在新版本&#xff08;5.0&#xff0b;&#xff09;不再有效&#xff01; EditPlus 是一个著名的代码文本编辑器。目前网上有其他人翻译的版本&#xff0c;但均存在零星的翻译错误。为此&#xff0c;我重新汉化了 EditPlus 的界面。 …

EditPlus4.0汉化+破解注册

1.官网下载并安装EditPlus软件包 https://www.editplus.com/download.html 2.下载官方推荐汉化程序&#xff0c;选择对应版本号 http://www.cnblogs.com/hanzisearcher/archive/2012/09/14/editplus.html 3.将解压缩得到的汉化文件“editplus.exe”直接覆盖至editplus安装目录…

强大的editplus 5.7

EditPlus是一款由韩国 Sangil Kim &#xff08;ES-Computing&#xff09;出品的小巧但是功能强大的可处理文本、HTML和程序语言的Windows编辑器&#xff0c;你甚至可以通过设置用户工具将其作为C,Java,Php等等语言的一个简单的IDE。 EditPlus&#xff08;文字编辑器&#xff0…

EditPlus 5.0 激活+汉化

EditPlus5.0注册码 注册名 Vovan 注册码 3AG46-JJ48E-CEACC-8E6EW-ECUAW EditPlus5.0汉化 各位网友&#xff1a;4.0 版本以前的注册码在新版本&#xff08;5.0&#xff0b;&#xff09;不再有效&#xff01; EditPlus 是一个著名的代码文本编辑器。目前网上有其他人翻译的版本&…

Editplus下载安装

Editplus简介 Editplus是一款很受欢迎的编辑器。简单的解释editplus软件的话&#xff0c;它就是一款功能更强大的记事本。除了普通的文本编辑之外&#xff0c;还有很多的其他特点。 默认支持HTML、CSS、PHP、ASP、Perl、C/C、Java、JavaScript和VBScript等语法高亮显示&#x…

EditPlus的安装与破解

过程及其简单&#xff0c;就两步&#xff1a; 1&#xff0c;下载 2&#xff0c;安装&#xff0c;反正占用不了什么空间&#xff0c;直接下一步下一步就可以了。 3&#xff0c;破解&#xff0c;记得先到http://www.jb51.net/tools/editplus/生成注册码&#xff0c;再断网输入。…