Protobuf之proto文件编写规则

2023-11-10

一. 简单介绍

protobuf文件:就是定义你要的消息(类似java中的类)和消息中的各个字段及其数据类型(类似java类中的成员变量和他的数据类型)

 

二. Protobuf消息定义


1、消息由至少一个字段组合而成,类似于C语言中的结构。每个字段都有一定的格式。

字段格式:限定修饰符① | 数据类型② | 字段名称③ | = | 字段编码值④ | [字段默认值⑤]

2、文件开头syntax="proto2"; 表明使用protobuf的编译器版本为v2,目前最新的版本为v3。

3、 package addressbook; 声明了一个包名,用来防止不同的消息类型命名冲突,类似于 namespace 。

 

1)限定修饰符包含 required\optional\repeated

Required: 表示是一个必须字段,必须相对于发送方,在发送消息之前必须设置该字段的值,对于接收方,必须能够识别该字段的意思。发送之前没有设置required字段或者无法识别required字段都会引发编解码异常,导致消息被丢弃。

Optional:表示是一个可选字段,可选对于发送方,在发送消息时,可以有选择性的设置或者不设置该字段的值。对于接收方,如果能够识别可选字段就进行相应的处理,如果无法识别,则忽略该字段,消息中的其它字段正常处理。---因为optional字段的特性,很多接口在升级版本中都把后来添加的字段都统一的设置为optional字段,这样老的版本无需升级程序也可以正常的与新的软件进行通信,只不过新的字段无法识别而已,因为并不是每个节点都需要新的功能,因此可以做到按需升级和平滑过渡。

Repeated:表示该字段可以包含[0,N]个元素。其特性和optional一样,但是每一次可以包含多个值。可以看作是在传递一个数组的值。 

 

2)数据类型 

Protobuf定义了一套基本数据类型。几乎都可以映射到C++\Java等语言的基础数据类型.    

    

protobuf 数据类型

描述

打包

C++语言映射

bool

布尔类型

1字节

bool

double

64位浮点数

N

double

float

32为浮点数

N

float

int32

32位整数、

N

int

uin32

无符号32位整数

N

unsigned int

int64

64位整数

N

__int64

uint64

64为无符号整

N

unsigned __int64

sint32

32位整数,处理负数效率更高

N

int32

sing64

64位整数 处理负数效率更高

N

__int64

fixed32

32位无符号整数

4

unsigned int32

fixed64

64位无符号整数

8

unsigned __int64

sfixed32

32位整数、能以更高的效率处理负数

4

unsigned int32

sfixed64

64为整数

8

unsigned __int64

string

只能处理 ASCII字符

N

std::string

bytes

用于处理多字节的语言字符、如中文

N

std::string

enum

可以包含一个用户自定义的枚举类型uint32

N(uint32)

enum

message

可以包含一个用户自定义的消息类型

N

object of class

 

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

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

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

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

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

3)字段名称

字段名称的命名与C、C++、Java等语言的变量命名方式几乎是相同的。

protobuf建议字段的命名采用以下划线分割的驼峰式。例如 first_name 而不是firstName.

4)字段编码值

有了该值,通信双方才能互相识别对方的字段。当然相同的编码值,其限定修饰符和数据类型必须相同。

编码值的取值范围为 1~2^32(4294967296)。

其中 1~15的编码时间和空间效率都是最高的,编码值越大,其编码的时间和空间效率就越低(相对于1-15),当然一般情况下相邻的2个值编码效率的是相同的,除非2个值恰好实在4字节,12字节,20字节等的临界区。比如15和16.

1900~2000编码值为Google protobuf 系统内部保留值,建议不要在自己的项目中使用。

protobuf 还建议把经常要传递的值把其字段编码设置为1-15之间的值。

消息中的字段的编码值无需连续,只要是合法的,并且不能在同一个消息中有字段包含相同的编码值。

建议:项目投入运营以后涉及到版本升级时的新增消息字段全部使用optional或者repeated,尽量不实用required。如果使用了required,需要全网统一升级,如果使用optional或者repeated可以平滑升级。

 

5)默认值。

当在传递数据时,对于required数据类型,如果用户没有设置值,则使用默认值传递到对端。当接受数据是,对于optional字段,如果没有接收到optional字段,则设置为默认值。

 

 

三. Protobuf其它可选项


Protocol Buffer允许我们在.proto文件中定义一些常用的选项,这样可以指示Protocol Buffer编译器帮助我们生成更为匹配的目标语言代码。

Protocol Buffer内置的选项被分为以下三个级别:

  1. 文件级别,这样的选项将影响当前文件中定义的所有消息和枚举。
  2. 消息级别,这样的选项仅影响某个消息及其包含的所有字段。
  3. 字段级别,这样的选项仅仅响应与其相关的字段。

java_package可选项

java_package (file option): 是文件级别的选项,表明生成java类所在的包。如果在.proto文件中没有明确的声明java_package,就采用默认的包名。

当然了,默认方式产生的 java包名并不是最好的方式,按照应用名称倒序方式进行排序的。如果不需要产生java代码,则该选项将不起任何作用。

与此同时,生成的Java文件也将会自动存放到指定输出目录下的com/example/foo子目录中。

如:option java_package = "com.example.foo";

 

java_outer_classname可选项

java_outer_classname (file option): 是文件级别的选项,表明想要生成Java类的名称。如果在.proto文件中没有明确的java_outer_classname定义,

生成的class名称将会根据.proto文件的名称采用驼峰式的命名方式进行生成。如(foo_bar.proto生成的java类名为FooBar.java),如果不生成java代码,

则该选项不起任何作用。

如:option java_outer_classname = "Ponycopter";

 

注:主要是因为Java中要求同一个.java文件中只能包含一个Java外部类或外部接口,而C++则不存在此限制。因此在.proto文件中定义的消息均为

指定外部类的内部类,这样才能将这些消息生成到同一个Java文件中。在实际的使用中,为了避免总是输入该外部类限定符,可以将该外部类静态

引入到当前Java文件中,

如:import static com.company.project.LYPhoneMessage.*。

 

四. 注意事项


1)关于import

protobuf 接口文件可以像C语言的h文件一个,分离为多个,在需要的时候通过 import导入需要对文件。其行为和C语言的#include或者java的import的行为大致相同。

2)关于package

避免名称冲突,可以给每个文件指定一个package名称,对于java解析为java中的包。对于C++则解析为名称空间。

3)关于message

支持嵌套消息,消息可以包含另一个消息作为其字段。也可以在消息内定义一个新的消息。

关于enum

枚举的定义和C++相同,但是有一些限制。

枚举值必须大于等于0的整数。

使用分号(;)分隔枚举变量而不是C++语言中的逗号(,)

4)message示例注意事项

示例:

syntax="proto2";

package FunMember; //命名空间

//分页请求参数

message PagerRequest{

   optional int32 PageIndex=1;

   required PageSize=2;

   repeated User Modle=3;

}

message User{

   int32 userId=1;

   int32 memberId=2;

}

 

注意事项:

1、如果ProtoGenTools工具下载的是2.0的,则proto文件中开头一句

syntax="proto2";这里也必须是proto2,如果定义为proto3就会报错;

 

2、生成C#的.cs文件,使用的是protogen.exe工具,

生成Java,C#,Python文件,使用的是protoc.exe工具;

 

3、生成C#的.cs文件,定义proto文件的message消息时,变量前面必须添加修饰符:required\optional\repeated,否则报错;

生成Java,C#,Python文件,,定义proto文件的message消息时,变量前面不能添加修饰符,否则报错;

 

 

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Protobuf之proto文件编写规则 的相关文章

  • 消息序列化工具-protobuf介绍及安装使用技巧

    简介 protobuf是google团队开发的用于高效存储和读取结构化数据的工具 xml json也可以用来存储此类结构化数据 xff0c 但是使用protobuf表示的数据能更加高效 xff0c 并且将数据压缩得更小 xff0c 大约是j
  • ubuntu 18.04安装protobuf

    今天需要安装protobuf 在网上搜了一篇教程 xff0c 但是篇幅太长 xff0c 于是对其进行简化一下 原文 1 96 96 96 git clone https github com protocolbuffers protobuf
  • C#使用ProtoBuf

    1 Google ProtoBuf 经过测试 xff0c protobuf比json存储效率还是要高 xff0c 即时号称最快的fastjson也没有protobuf快 xff0c 这里为了使用 c 做一个客户端兼容 xff0c 所以也需要
  • 通讯协议序列化解读(一) Protobuf详解教程

    https www cnblogs com tohxyblog p 8974641 html
  • golang gRPC:根据.protobuf文件生成go代码

    文章目录 golang gRPC xff1a 根据 protobuf文件生成go代码根据 protobuf文件生成go代码根据proto生成go放在什么位置是最佳实践ProtoBuf 生成 Go 代码去掉 JSON tag omitempt
  • [cartographer] 9. proto配置文件读取

    目录 1 proto文件 2 lua配置文件 3 代码 1 xff09 读取lua文件 2 xff09 赋值给proto options 获取proto参数值有两种方式 xff1a 1 xff09 lua文件 2 xff09 通过servi
  • vs2015的OpenCV3.2.0编译

    我们希望添加第三方功能模块和库或者针对特定cpu和gpu的编译调整优化选项 这样的需求就需要自己去编译opencv了 准备东西 opencv opencv contrib cmake 还有两个文件 因为可能是国内的原因 在configure
  • mac下编译protobuf c++

    由于protobuf官网的文档是英文版的 并且并没有比较详细的说明 可能说得很清楚了 只是我这种英文渣看不懂 学习起来着实费了一翻功夫 在此 记录一下学习过程 希望尽量详细 一 编译过程需要的工具 1 protobuf源码 下载地址 htt
  • protobuf 2.0版本排查必填字段未填的方法

    在proto2 0版本中 如果required字段没有填写 那么proto编码字符串发给对方进行parse时 对方会parse失败 因此有必要在发送前检查一下是否存在这种情况 特别是在debug阶段 1 为了获取proto序列化的错误信息
  • 解决protobuf内存泄漏的3种办法

    1 protobuf对象是如何释放 数组 内存的 毫无疑问是 通过调用析构函数 只要让protobuf定义的对象调用析构函数 无论嵌套了多少层数据 包含了多少个数组都可以释放new出来的内存 2 protobuf对象Clear 接口和STL
  • mac环境下Maven实现ProtoBuf编译

    mac环境下Maven实现protobuf编译 1 Maven项目创建 File gt new gt Project gt 输入项目名称 gt finish 2 在项目中创建proto目录 该目录用来保存 proto文件 此处将proto目
  • protobuf c++编程笔记

    文章目录 字段内容的定义 修饰符 字段类型 引用方式 不同字段的方法 1 optional修饰的基本类型 2 optional修饰的对象类型 3 repeated修饰的基本类型 4 repeated修饰的对象类型 序列化 反序列化 字段内容
  • gRPC的介绍、安装与使用

    1 gRPC是什么 在 gRPC里客户端应用可以像调用本地对象一样直接调用另一台不同的机器上服务端应用的方法 使得您能够更容易地创建分布式应用和服务 与许多 RPC系统类似 gRPC也是基于以下理念 定义一个服务 指定其能够被远程调用的方法
  • google_protobuf数据类型

    原文链接 google protobuf数据类型 要通信 必须有协议 否则双方无法理解对方的码流 在protobuf中 协议是由一系列的消息组成的 因此最重要的就是定义通信时使用到的消息格式 Protobuf消息定义 消息由至少一个字段组合
  • protobuf详细介绍和使用

    一 protobuf初识 一 protocol buffers 是什么 protocol buffers 是一种灵活 高效 自动化机制的结构数据序列化方法 可类比 XML 但是比 XML 更小 更快 更为简单 你可以定义数据的结构 然后使用
  • Protobuf之proto文件编写规则

    一 简单介绍 protobuf文件 就是定义你要的消息 类似java中的类 和消息中的各个字段及其数据类型 类似java类中的成员变量和他的数据类型 二 Protobuf消息定义 1 消息由至少一个字段组合而成 类似于C语言中的结构 每个字
  • Ubuntu 下配置protobuf

    首先得到 protobuf 相应的包文件 在终端上输入如下 wget http protobuf googlecode com files protobuf 2 5 0 tar gz 由于 现在 protobuf 2 5 0 tar gz已
  • protobuf在C#项目中的使用

    protobuf在C 项目中的使用 在C 项目中 有时候会使用到使用到protobuf来作为通信时数据交换的格式 protobuf ProtocolBuffer 简称PB 是google 的一种数据交换的格式 这是一种二进制的格式 比使用x
  • 2. IDEA + maven + protobuf配置(on mac)

    1 絮絮叨叨 都说懒惰是人类进步的源泉 有时候想想还真就那么回事 学习了如何使用protoc命令编译 重度依赖IDEA且已经习惯了maven的我 就在想是否能在IDEA中一键编译 proto文件 2 vscode配置protobuf编辑环境
  • 如何将 Google proto 时间戳转换为 Java LocalDate?

    我们需要将 Google Protobuf 时间戳转换为正常日期 在这种情况下 有没有办法将 Google Proto 缓冲区时间戳转换为 JavaLocalDate直接地 tl dr 作为 UTC 时刻 转换为java time Inst

随机推荐

  • 【cdk的使用】 C语言 零拷贝 链表 队列 栈的使用

    Github地址 https github com wujin1989 cdk cdk的 list 是基于双向循环链表实现 queue 和 stack 基于 list实现 所以cdk用一个双向循环链表实现了三种数据结构 如何使用cdk的链表
  • Python ·保险理赔分析:数据分析

    介绍 提示 这里可以添加系列文章的所有文章的目录 目录需要自己手动添加 在本笔记本中 我们将仔细研究保险索赔 并弄清一些有关血压 BMI 糖尿病 吸烟 年龄和性别等条件如何影响索赔价值的事实 我们将使用散点图 饼图 直方图等通过探索性数据分
  • dnn回归预测_Keras之DNN:基于Keras(sigmoid+linear+mse+predict)利用DNN实现回归预测——DIY多分类数据集&预测新数据点...

    Keras之DNN 基于Keras sigmoid linear mse predict 利用DNN实现回归预测 DIY多分类数据集 预测新数据点 目录 输出结果 实现代码 输出结果 实现代码 coding utf 8 Xa Xb for
  • postman 下载图片_postman测试上传图片接口步骤教程

    Postman是一款功能强大的网页调试与发送网页HTTP请求的Chrome插件 前端也要学会使用 只有这样 当接口调试不通的时候 用测试工具 才能够更有底气的甩一张截图给你家的后端 瞧 这是你写的bug 现在来说一下 怎么测试一个上传图片的
  • 工作日志【 SQL内部规范-ETL银行项目 】

    工作日志 SQL内部规范 ETL银行项目 一 表结构设计 建表时 首先要确定表的业务唯一键 即该表的唯一索引由哪些字段构成 不建议创建没有唯一索引的表 如果要修改表的唯一索引 一定要严格评审 前台 表结构变更 F层的表需要通知JAVA开发
  • SpringCloud项目下使用分布式事务seata TCC模式与AT模式例子

    SpringCloud项目下使用分布式事务seata TCC模式与AT模式例子
  • 3-2 特征二值化

    特征二值化 请参考 数据准备和特征工程 中的相关章节 调试如下代码 基础知识 import pandas as pd pm25 pd read csv home aistudio data data20505 pm2 csv pm25 he
  • 使用Flex&Bison创建新的编程语言

    编译器基本流程 对源文件进行扫描 将源文件的字符流拆分分一个个的词 记号 此为词法分析 根据语法规则将这些记号构造出语法树 此为语法分析 对语法树的各个节点之间的关系进行检查 检查语义规则是否被违背 同时对语法树进行必要的优化 此为语义分析
  • 苹果个人公司类型开发者账号申请(99美元)详解

    最近有用 记录一下 谈到苹果开发者账号 我们需要区分一下个人账号 公司账号和企业账号这三种 还有一种是教育账号 这个就不多说了 个人账号 个人申请用于开发苹果app所使用的账号 仅限于个人使用 申请比较容易 99 公司账号 以公司的名义申请
  • jqgrid 自定义搜索的实现 , 后台实现

    好久没写过博客了 新入职公司比较忙 咳咳 其实是比较懒 最近公司要求做一个后台 于是直接巴拉了bootstrap 的ace折叠菜单改造了下 由于大部分都是数据交互 频繁使用了 ace中包含的 jqgrid 要做后台的朋友可以去搜索一下ace
  • C#中@的用法总结(转)

    本文实例汇总了C 中 的用法 对C 程序设计来说有不错的借鉴价值 具体如下 一 字符串中的用法 1 学过C 的人都知道C 中字符串常量可以以 开头声名 这样的优点是转义序列 不 被处理 按 原样 输出 即我们不需要对转义字符加上 反斜扛 就
  • libxlsxwriter初体验

    C 如何写Excel 大家时间都这么宝贵 没有起因的问题是不值得被优先研究的 这篇博客的起因就是希望找到一个比较合适于C 的开源库 用以在C 中生成Excel文档 其实C 可用的开源Excel库 很多博主都已经撰文提及 例如 c 操作exc
  • 第六篇 TCP协议

    1 专业名词缩写 应用层头 ah Application Header 表示层头 ph Presentation Header 会话层头 sh Session Header 传输层头 th Transport Header 网络层头 nh
  • cJson数组的生成与解析

    cJson数组的生成与解析 cJosn官方源码地址 https sourceforge net projects cjson 使用json偶尔会遇到数组 每次都要去查相关函数 去解析或者生成 在此做一次记录 方便以后使用 按照我自己的使用习
  • 基于opencv视觉图像处理的巡线小车设计(stm32+树莓派+usb摄像头)

    功能说明 1 视觉巡线 usb摄像头 opencv 2 遇到红灯停车 红灯出现在小车右前方时 3 固定动作避障 光电对管 4 按键启动 急停 4 按键调整运行速度 资料说明 本小车图像处理部分在树莓派中实现 小车控制部分在stm32中实现
  • android ListView 滚动加载item

    悉Android的朋友们都知道 不管是微博客户端还是新闻客户端 都离不开列表组件 可以说列表组件是Android数据展现方面最重要的组件 我们今天就要讲一讲列表组件ListView加载数据的相关内容 通常来说 一个应用在展现大量数据时 不会
  • ArcGis系列-java发布空间表为地图服务(map)

    1 实现思路 使用java调用cmd命令执行python脚本 python环境使用arcgis pro安装目录下的 ArcGIS Pro bin Python envs arcgispro py3 作为地图服务应该可以支持添加样式文件 发布
  • 分布式定时任务

    本文引用了谷粒商城的课程 定时任务 定时任务是我们系统里面经常要用到的一些功能 如每天的支付订单要与支付宝进行对账操作 每个月定期进行财务汇总 在服务空闲时定时统计当天所有信息数据等 定时任务有个非常流行的框架Quartz和Java原生AP
  • Latex技巧(持续更新)(\newcommand{}{})

    自定义一个新命令 newcommand tcr textcolor red 为了方便设置文本颜色为红色而定义的简化命令 code documentclass article usepackage xcolor newcommand tcr
  • Protobuf之proto文件编写规则

    一 简单介绍 protobuf文件 就是定义你要的消息 类似java中的类 和消息中的各个字段及其数据类型 类似java类中的成员变量和他的数据类型 二 Protobuf消息定义 1 消息由至少一个字段组合而成 类似于C语言中的结构 每个字