protobuf介绍和语法

article/2025/8/30 8:12:20

目录

前言

语法

标识符 

字段

字段类型

proto2和proto3区别


前言

        Protobuf即Protocol Buffers,是Google公司开发的一种跨语言和平台的序列化数据结构的方式,是一个灵活的、高效的用于序列化数据的协议。
        与XML和JSON格式相比,protobuf更小、更快、更便捷。protobuf是跨语言的,并且自带一个编译器(protoc),只需要用protoc进行编译,就可以编译成Java、Python、C++、C#、Go等多种语言代码,然后可以直接使用,不需要再写其它代码,自带有解析的代码。
        只需要将要被序列化的结构化数据定义一次(在.proto文件定义),便可以使用特别生成的源代码(使用protobuf提供的生成工具)轻松的使用不同的数据流完成对结构数据的读写操作。甚至可以更新.proto文件中对数据结构的定义而不会破坏依赖旧格式编译出来的程序。

Protobuf的优点如下:

  • 性能号,效率高
    序列化后字节占用空间比XML少3-10倍,序列化的时间效率比XML快20-100倍。
  • 有代码生成机制
    将对结构化数据的操作封装成一个类,便于使用。
  • 支持向后和向前兼容
    当客户端和服务器同时使用一块协议的时候, 当客户端在协议中增加一个字节,并不会影响客户端的使用
  • 支持多种编程语言
    Protobuf目前已经支持Java,C++,Python、Go、Ruby等多种语言。

Protobuf的缺点如下:

  • 二进制格式导致可读性差
  • 缺乏自描述

语法

        protobuf协议文件名后缀名为.proto。一个简单的protobuf协议如下:

  1 syntax="proto3";2 3 package protobuf.addressbook;4 5 enum PhoneType6 {7   MOBILE = 0;8   HOME = 1;9   WORK = 2;10 }11 12 message Person13 {14   optional string name = 1;15   optional uint32 age = 2;16   optional string email = 3;17 18   message PhoneNumber19   {20     optional string number = 1;21     optional PhoneType type = 2;22   }23 24   repeated PhoneNumber phone = 4;                                                                                                                                                                                                      25                                            26 }                                          27                                            28                              29 message AddressBook          30 {                            31   repeated Person person = 1;32 }

标识符 

  • syntax:标识使用的protobuf是哪个版本。上面表示使用的是3.x版本。
  • package:标识生成目标文件的包名。在C++中表示的是命名空间。上面。表示生成的类和函数在protobuf命名空间的addressbook命令空间下。
  • enum:表示一个枚举类型。会在目标.h文件中自动生成一个枚举类型。
  • message:标识一条消息。会在目标文件中自动生成一个类。

字段

        字段格式:

        role type name = tag [default value]

role 有三种取值:

        required:该字段必须给值,不能为空。否则message被认为是未初始化的。如果试图建立一个未初始化的message将会抛出RuntimeException异常,解析未初始化的message会抛出IOException异常。

        optional:表示该字段是可选值,可以为空。如果不设置,会设置一个默认值。也可以自定义默认值。如果没有自定义默认值,会是用系统默认值。

        repeated:表示该字段可以重复,可等同于动态数组。

注意:required字段是永久性的,如果之后不使用该字段,或者该字段标识改为optional或repeated,那么使用就接口读取新协议时,如果发现没有该字段,会认为该消息不完整,会拒收或者丢弃该消息。

字段类型

N 表示打包的字节并不是固定。而是根据数据的大小或者长度。

例如int32,如果数值比较小,在0~127时,使用一个字节打包。

关于枚举的打包方式和uint32相同。

关于message,类似于C语言中的结构包含另外一个结构作为数据成员一样。

关于 fixed32 和int32的区别。fixed32的打包效率比int32的效率高,但是使用的空间一般比int32多。因此一个属于时间效率高,一个属于空间效率高。根据项目的实际情况,一般选择fixed32,如果遇到对传输数据量要求比较苛刻的环境,可以选择int32.

proto2和proto3区别

        总的来说proto3比proto2支持跟多语言,但是更加简洁。去除了复杂的语法和特性。

  • 必须指明版本
syntax = "proto3";
  • 字段规则移除了"required",并把optional改名为了singlar,但是亲测,optional还可以用。

        实际在proto2中也不推荐使用required,因为该字段是永久性的。如果以后因为某种原因,想不用该字段,或者要将该字段改成optional或者repeated,那么使用旧接口读取新的协议时,如果发现没有该字段,他们会认为该字段是不完整的,会拒接接收该消息,或者直接丢弃。

  • “repeated”字段默认采用 packed 编码

        在 proto2 中,需要明确使用 [packed=true] 来为字段指定比较紧凑的 packed 编码方式。

  • 移除了 default 选项

        在 proto2 中,可以使用 default 选项为某一字段指定默认值。在 proto3 中,字段的默认值只能根据字段类型由系统决定。也就是说,默认值全部是约定好的,而不再提供指定默认值的语法。

        

        在字段被设置为默认值的时候,该字段不会被序列化。这样可以节省空间,提高效率。

但这样就无法区分某字段是根本没赋值,还是赋值了默认值。这在 proto3 中问题不大,但在 proto2 中会有问题。

  • 枚举类型的第一个字段约定必须为 0 
  • 移除了对分组的支持

分组的功能完全可以用消息嵌套的方式来实现,并且更清晰。

  • 移除了对扩展的支持,新增了 Any 类型

proto3 中新增的 Any 类型有点像 C/C++ 中的 void* 

  • 增加了 JSON 映射特性

  •  Map

        如果要创建一个关联映射,Protobuf提供了一种快捷的语法:

        key_type可以是任意Integer或者string类型(除了floating和bytes的任意标量类型都可以),value_type可以是任意类型,但不能是map类型。

map<key_type, value_type> map_field = N;

注意:

  • Map的字段可以是repeated。
  • 序列化后的顺序和map迭代器的顺序是不确定的,所以不要期望以固定顺序处理Map。
  • 当为.proto文件产生生成文本格式的时候,map会按照key 的顺序排序,数值化的key会按照数值排序。

map语法序列化后等同于如下内容,所以Map不经常使用。

message MapFieldEntry {key_type key = 1;value_type value = 2;
}
repeated MapFieldEntry map_field = N;
  • Oneof

        Oneof定义用来代表在实现的时候,该组属性中的字段有且只能有一个被定义,不能出现多个。

message SampleMessage {oneof test_oneof {string name = 4;SubMessage sub_message = 9;}
}

上述定义中只能出现name或者sub_message的出现,不能同时出现。

注意:

  • Oneof不能出现repeated类型
  • 重复传递值到Oneof多个域仅仅最后的会生效,其它的将被忽略掉。

protobuf的编译和使用可以看:下一篇博客

        

 参考文档:

ProtoBuf 语法简介_n大橘为重n的博客-CSDN博客_protobuf语法

Protobuf简介_Shower稻草人的博客-CSDN博客_protobuf介绍

【Protocol Buffer】Protocol Buffer入门教程(三):proto3与proto2的区别_沧海一笑的技术博客_51CTO博客

Protobuf简介_Shower稻草人的博客-CSDN博客_protobuf介绍


http://chatgpt.dhexx.cn/article/yg3l9diW.shtml

相关文章

Protobuf:一种更小、更快、更高效的协议

C/CLinux服务器开发/后台架构师知识体系 Protobuf介绍 Protobuf (Protocol Buffers) 是谷歌开发的一款无关平台&#xff0c;无关语言&#xff0c;可扩展&#xff0c;轻量级高效的序列化结构的数据格式&#xff0c;用于将自定义数据结构序列化成字节流&#xff0c;和将字节流反…

win10商店打不开_win10应用商店闪退是咋回事呢

win10虽然具有闪电般的开机速度&#xff0c;并且还新增了很多功能。但比较是全新的操作系统&#xff0c;所以难免会存在一些故障&#xff0c;这里小编就给大家讲讲win10应用商店闪退打不开怎么解决。 方法一 1&#xff0c;首先&#xff0c;打开开始菜单&#xff0c;进入设置&am…

电脑安装Linux闪退,win10系统运行内置Linux系统闪退如何处理

我们在win10系统电脑的使用中&#xff0c;有小伙伴在Linux系统的使用中出现了问题&#xff0c; win10系统运行内置Linux系统闪退的情况出现了&#xff0c;这是什么原因导致的呢&#xff0c;我们在win10系统运行内置Linux系统闪退如何处理&#xff0c;今天小编就来跟大家分享一下…

Java版mc闪退_本文传授win10运行mc闪退的具体操作对策

我们在使用电脑的时候遇到了win10运行mc闪退问题确实比较难受&#xff0c;要是你的电脑技术没有达到一定的水平&#xff0c;可能就不能解决这个win10运行mc闪退的情况。我们应当如何处理这个问题呢&#xff1f;小编先给大伙说说简单的措施&#xff1a;1、确保电脑中安装了 .NET…

(2022.5.27)【Win10】Windows10重置后微软商店闪退打不开、图片闪退打不开、UWP应用闪退打不开——可能的解决方案

更新日志 20220609 增加注意事项 注意事项 经过多为网友的反馈&#xff0c;目前这个方法是无法直接解决微软商店打不开的问题。因此&#xff0c;基于我目前的了解&#xff08;6月9日&#xff09;&#xff0c;如果大家遇到这个问题&#xff0c;真的只能重新 U 盘安装系统了。…

win10内置计算机和天气闪退,win10系统中天气闪退怎么办?Win10天气应用闪退问题解决方法...

win10系统中天气闪退怎么办&#xff1f;最近有部分用户在安装了win10系统后发现自带的天气应用出现闪退的情况&#xff0c;点击天气应用&#xff0c;发现它启动了很久&#xff0c;然后就自动关闭了。之后再点击天气应用就闪退&#xff0c;打不开。而尝试打开别的应用却可以正常…

解决WIN10下应用商店不能用,闪退的情况

解决WIN10下应用商店不能用,闪退的情况 先说下我的情况,也是博主手贱,经常看PC上的某个文件或者程序不顺眼的话就会想办法把它干掉,为此重装过几次系统… 这一次是装了win10的周年更新后,烦人的cortana,onedrive等一些我不想要的APP又回来了,在暴力清理这些APP的时候,需要特殊…

win10java闪退怎么办_Win10应用打不开或闪退怎么办?解决方案在此

可能有一些用户升级Win10之后遇到了应用商店、应用打不开或闪退的问题&#xff0c;此时可尝试通过下面的一些方法来解决。 1、点击任务栏的搜索(Cortana小娜)图标&#xff0c;输入Powershell&#xff0c;在搜索结果中右键单击Powershell&#xff0c;选择“以管理员身份运行”。…

win10的c语言程序闪退,Win10专业版软件打不开闪退怎么办?

现在用到最多的Win10系统是Win10专业版&#xff0c;用户重装Win10专业版系统的目的就是为了解决电脑遇到的问题&#xff0c;然而重装系统后还是会出现许许多多的问题&#xff0c;比如说部分软件打不开了&#xff0c;闪退的问题。如果您也遇到了相同的问题&#xff0c;下面就是小…

win10安装虚拟机闪退_win10应用商店战争机器4闪退,无法运行。

创建日期 2018/01/07 win10应用商店战争机器4闪退&#xff0c;无法运行。 日志名称: System 来源: Microsoft-Windows-DistributedCOM 日期: 2018-01-07 14:05:10 事件 ID: 10001 任务类别: 无 级别: 错误 关键字:…

右击计算机管理打开会闪退,win10应用商店为什么会闪退 win10应用商店出故障怎么修复...

win10系统有个应用商店&#xff0c;在商店里用户可以下载一些软件应用&#xff0c;很多用户反馈win10应用商店老是闪退&#xff0c;重启也没有用&#xff0c;这该怎么办&#xff1f;下面小编为大家科普下win10应用商店闪退的解决方案&#xff0c;希望可以帮助到大家。 win10应用…

win10的c语言程序闪退,win10内置应用出现闪退怎么回事? win10打开应用总闪退的解决方法...

Windows10操作系统新增加很多实用的功能&#xff0c;对大家操作电脑有很大帮助。Win10专业版系统自带有相机功能、地图功能、时钟功能&#xff0c;同时还有一个应用商店功能&#xff0c;有的小伙伴说打开内置应用时出现闪退&#xff0c;究竟是哪里出现问题&#xff1f;针对此问…

win10的c语言程序闪退,win10 1909系统出现应用闪退如何解决

许多用户在升级更新到win10 1909版本系统之后&#xff0c;反映说遇到这样一个问题&#xff0c;就是使用应用的时候会出现闪退的现象&#xff0c;该怎么处理呢&#xff0c;下面给大家带来win10 1909系统出现应用闪退的解决措施。 一、重装应用 将闪退的应用卸载之后重新安装一下…

Window10 应用商店闪退问题

新装win10后打开应用商店&#xff0c;搜索软件直接闪退&#xff0c;查看了网上前人留下的经验发现还是没有解决问题&#xff0c;后来点开了电脑的设置 默认是选中第二项&#xff0c;点击第一项后&#xff0c;应用商店可以使用了 当然选中开发人员模式应用商店也是可以使用的

Win10应用商店、应用打不开或闪退的解决方法

越来越多小伙伴都将系统升级成Win10正式版了,win10功能强大令不少朋友感到非常满意,但也有一些朋友升级后却遇到了一些问题,比如应用商店、应用打不开或闪退的问题,今天快启动小编就跟大家介绍Win10应用商店、应用打不开或闪退的解决方法。 1、点击任务栏的搜索(Cortana小娜…

WIN10应用商店(MicrosoftStore)闪退解决方法!!!

本文参考了&#xff1a; CSDN博主「DreamOneDay」的文章https://blog.csdn.net/zyhj2010/article/details/52232749知乎作者千千之雪的文章https://www.zhihu.com/question/31001796/answer/1099015956 本方法适用于&#xff1a;更改过C:\ProgramFiles\WindowsApps权限的用户 如…

win10应用及应用商店闪退有效解决办法

近日遇到win10应用及应用商店闪退问题&#xff0c;在网上找寻各种方法&#xff0c;最终解决&#xff0c;记录下来&#xff0c;供以后查询。 方法 1/步骤1 1、在任务栏的搜索框中输入“Powershell”&#xff0c;然后在搜索结果中找到windows Powershell 鼠标右键单击并选择“以…

第6集丨JavaScript 使用原型(prototype)实现继承——最佳实战3

目录 一、原型继承与属性拷贝1.1 功能说明1.2 功能测试 二、多重继承2.1 功能实现2.2 功能测试 三、寄生式继承四、构造器借用4.1 简单实现4.2 进化版4.2.1 功能实现4.2.2 案例测试 五、借用构造器和原型复制六 综合案例6.1 需求说明6.2 代码实现 一、原型继承与属性拷贝 1.1 功…

Jstorm基础架构

整体架构 深度基于Zookeeper的调度系统。 Jstorm ZK路径 /-{storm.zookeeper.root} -- Jstorm在zookeeper上的根目录,需要在jstorm中配置~/.jstorm/storm.yaml| ||-/nimbus_master -- nimbus_master 的ip和端口| |-/nim…

JStorm使用总结

JStorm 是一个类似Hadoop MapReduce的系统&#xff0c; 用户按照指定的接口实现一个任务&#xff0c;然后将这个任务递交给JStorm系统&#xff0c;JStorm将这个任务跑起来&#xff0c;并且按7 * 24小时运行起来&#xff0c;一旦中间一个Worker 发生意外故障&#xff0c; 调度器…