protobuf 讲解

一、序列化概念回顾

二、什么是PB

将结构化数据进行序列化的一种方式

三、PB的特点

语言无关、平台无关:即PB支持Java,C++、Python等多种语言。支持多个平台

高效:即比XML更小,更快,更为简单。

扩展性、兼容性好:你可以更新数据结构,而不影响和破坏原有的旧程序。

使用特点:ProtoBuf是需要依赖通过编译生成的头文件和源文件来使用。

四、安装ProtoBuf

ProtoBuf下载地址:https://github.com/protocolbuffers/protobuf/releases

1、在windows安装

配置一下环境变量就可以了

protoc --version 打印出版本

2、在ubuntu下安装

下载依赖器

下载protoBuf

解压包 unzip

编译生成protobuf

一次执行下面的命令 大概需要半个小时左右

这里需要更改profile,修改环境变量

sudo vim /etc/profile

在里面添加下面的内容

#(动态库搜索路径) 程序加载运⾏期间查找动态链接库时指定除了系统默认路径之外的其他路径export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/protobuf/lib/
#(静态库搜索路径) 程序编译期间查找动态链接库时指定查找共享库的路径
export LIBRARY_PATH=$LIBRARY_PATH:/usr/local/protobuf/lib/
#执⾏程序搜索路径
export PATH=$PATH:/usr/local/protobuf/bin/
#c程序头⽂件搜索路径
export C_INCLUDE_PATH=$C_INCLUDE_PATH:/usr/local/protobuf/include/
#c++程序头⽂件搜索路径
export CPLUS_INCLUDE_PATH=$CPLUS_INCLUDE_PATH:/usr/local/protobuf/include/
#pkg-config 路径
export PKG_CONFIG_PATH=/usr/local/protobuf/lib/pkgconfig/

再执行这个命令:

source /etc/profile

另外需要说一下Centos用户在安装的时候需要用到这个命令

sudo yum install autoconf automake libtool curl make gcc-c++ unzip

五、使用ProtoBuf

使用protobuf,实现一个通讯录项目,一个版本一个版本的实现,从而有效推进protobuf的学习。

快速上手

目的:完整使用PB,学习基本语法。

在快速上手中,我们会编写第一个版本的通讯录1.0。

• 对⼀个联系⼈的信息使⽤PB进⾏序列化,并将结果打印出来。

• 对序列化后的内容使⽤PB进⾏反序列,解析出联系⼈信息并打印出来。

• 联系⼈包含以下信息:姓名、年龄。
通过通讯录1.0,我们便能了解使⽤ProtoBuf初步要掌握的内容,以及体验到ProtoBuf的完整使⽤流程。

步骤一:创建.protobuf

步骤二:进行编译

-I 指定搜索目录

步骤三:

对一个联系人的信息使用PB进行序列化,并将结果打印出来。

对序列化后的内容使用PB进行反序列化,解析出联系人信息并打印出来。

六、proto3语法详解

升级版本的通讯录

• 不再打印联系⼈的序列化结果,⽽是将通讯录序列化后并写⼊⽂件中。

• 从⽂件中将通讯录解析出来,并进⾏打印。
• 新增联系⼈属性,共包括:姓名、年龄、电话信息、地址、其他联系⽅式、备注。

1、字段规则、消息类型的定义和使用

新增联系人的属性。

repeated来定义一个数组。消息中可以包含该字段任意多次(包括零次),其中重复值的顺序会被保留。可以理解为定义了⼀个数组。

singular的规则,消息中可以包含该字段零次或⼀次(不超过⼀次)。proto3语法中,字段默认使⽤该规则。

可以嵌套定义message。

引入 phone文件

定义通讯录proto文件

把通讯录的信息写入文件,首先编写makefile文件。

里面调用的函数返回的是一个已经开辟好的空间所以我们可以使用这个空间直接对contact新增联系人。

查看二进制文件

读取文件

decode的使用

2、proto3语法理解enum类型

0必须存在,必须在第一个。

也可以定义在消息体内

不能让同级的enum类型中的成员系统,多个文件中的enum类型中的类型也不能同名。会编译报错。解决方法:可以包含一个命名空间进行隔离。

通讯录2.1,更新proto文件

设置联系人电话类型

修改打印函数

枚举类型会被默认设置。反序列化时会设置枚举值为0的枚举类型。

3、Any类型的讲解

Any类型可以被理解为是一个泛型类型。可以存储任意的消息类型。

通讯录2.2版本 使用Any字段存放联系人地址。

新增联系人地址

读出联系人地址

4、oneof类型讲解

2.3版本新增其他联系方式

只能设置一个其他联系方式

字段编号不能重复,不能使用repeated来修饰里面的值,

添加联系人的其他联系方式

读取联系人的其他联系方式

5、map类型的使用

2.4版本,增加备注

不能使用repeated来修饰,设置的kv值是无序的

设置联系人备注信息

打印备注信息

6、默认值讲解

反序列化消息时,如果被反序列化的⼆进制序列中不包含某个字段,反序列化对象中相应字段时,就会设置为该字段的默认值。不同的类型对应的默认值不同:

• 对于字符串,默认值为空字符串。
• 对于字节,默认值为空字节。
• 对于布尔值,默认值为false。
• 对于数值类型,默认值为0。
• 对于枚举,默认值是第⼀个定义的枚举值,必须为0。

• 对于消息字段,未设置该字段。它的取值是依赖于语⾔。• 对于设置了repeated的字段的默认值是空的(通常是相应语⾔的⼀个空列表)。

• 对于 消息字段 、 oneof字段 和 any字段 ,C++和Java语⾔中都有has_⽅法来检测当前字段是否被设置。

对于标量数据类型,在proto3语法下,没有生成has_方法。不确定是用户设置的还是一个默认值。

7、更新消息

新增字段

注意不要和老字段冲突即可

修改字段

• 禁⽌修改任何已有字段的字段编号。

• 若是移除⽼字段,要保证不再使⽤移除字段的字段编号。正确的做法是保留字段编号
(reserved),以确保该编号将不能被重复使⽤。不建议直接删除或注释掉字段。

• int32,uint32,int64,uint64和bool是完全兼容的。可以从这些类型中的⼀个改为另⼀个,
⽽不破坏前后兼容性。若解析出来的数值与相应的类型不匹配,会采⽤与C++⼀致的处理⽅案(例如,若将64位整数当做32位进⾏读取,它将被截断为32位)。
• sint32和sint64相互兼容但不与其他的整型兼容。• string和bytes在合法UTF-8字节前提下也是兼容的。

• bytes包含消息编码版本的情况下,嵌套消息与bytes也是兼容的。

• fixed32与sfixed32兼容,fixed64与sfixed64兼容。
• enum与int32,uint32,int64和uint64兼容(注意若值不匹配会被截断)。但要注意当反序
列化消息时会根据语⾔采⽤不同的处理⽅案:例如,未识别的proto3枚举类型会被保存在消息中,但是当消息反序列化时如何表⽰是依赖于编程语⾔的。整型字段总是会保持其的值。
• oneof:

◦ 将⼀个单独的值更改为新oneof类型成员之⼀是安全和⼆进制兼容的。

◦ 若确定没有代码⼀次性设置多个值那么将多个字段移⼊⼀个新oneof类型也是可⾏的。

◦ 将任何字段移⼊已存在的oneof类型是不安全的。

删除字段

不能直接删除已存在的字段,

如果要删除老子段,要保证不使用已经被删除的或者已经被注释掉的字段编号,会导致下列问题

如何不使用已经被注释掉的字段编号呢?

reserved保留项

指定保留的字段编号

会有一个错误发生

还可以这样写

结果:我们看到年龄不在使用前面的字段编号了

上面的生日信息哪里去了呢。被存放到了未知字段中。

未知字段

未知字段是什么?

• 未知字段:解析结构良好的protocolbuffer已序列化数据中的未识别字段的表⽰⽅式。例如,当旧程序解析带有新字段的数据时,这些新字段就会成为旧程序的未知字段。
• 本来,proto3在解析消息时总是会丢弃未知字段,但在3.5版本中重新引⼊了对未知字段的保留机制。所以在3.5或更⾼版本中,未知字段在反序列化时会被保留,同时也会包含在序列化的结果中。

从哪获取未知字段?

通过Reflection类中UnKnowFields()方法获取

打印未知字段

前后兼容性

向前兼容:⽼模块能够正确识别新模块⽣成或发出的协议。这时新增加的“⽣⽇”属性会被当作未 知字段(pb 3.5版本及之后)。
向后兼容:新模块也能够正确识别⽼模块⽣成或发出的协议。
前后兼容的作⽤:当我们维护⼀个很庞⼤的分布式系统时,由于你⽆法同时 升级所有 模块,为了保证 在升级过程中,整个系统能够尽可能不受影响,就需要尽量保证通讯协议的“向后兼容”或“向前兼容”。

8、option选项语法详解

option选项可以影响ProtoBuf的编译属性。用的不太多,所以我们可以用文档看一下就可以了。

七、通讯录4.0实现 --- 网络版

服务器

客户端

客户端调用接口req,调用返回resp。

客户端的.proto文件和服务器的相同

客户端的菜单编写

服务端书写 add del findALL findOne接口。每个接口会有req,resp协议。

序列化req

调用接口

反序列化req 新增一个联系人,持久化存储通讯录

序列化resp

反序列化resp

AddContact方法

protobuf远远比json的序列化和反序列化效率高。json的内存占用比protobuf多一倍。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/880954.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

WPF之UI进阶--控件样式与样式模板及词典

WPF的优势之一就是能够更加容易快捷的对窗体和控件的外面进行改造,换句话说,那就是UI设计个性化更加容易。主要是借助了样式、模板及词典来实现的。那么本篇博文就一一对他们进行介绍。 文章目录 一、样式1: 定义样式2: 使用Setter设置属性关于Property和…

C或C++判断指针是否指向同一块内存

有时需要判断指针是否指同一块内存,例如设计字符串时: (1)insert函数 (2) replace函数 (3)assign函数 难点是迭代器,判断是否同一个迭代器时,需要你在设计迭代器时加…

Kubernetes-环境篇-01-mac开发环境搭建

1、brew安装 参考知乎文章:https://zhuanlan.zhihu.com/p/111014448 苹果电脑 常规安装脚本(推荐 完全体 几分钟安装完成) /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)"苹果电脑 极…

Rstudio:强大的R语言集成开发环境(IDE)

Rstudio 应该是 R 语言使用的标配,尽管 Rstudio 的母公司 Posit 推出了新一代的集成开发环境 Positron,但其还处于开发阶段。作为用户不妨让其成熟后再使用,现阶段还是 Rstudio 更稳定。 如果你在生物信息学或统计学领域工作,R语言…

Python | Leetcode Python题解之第455题分发饼干

题目&#xff1a; 题解&#xff1a; class Solution:def findContentChildren(self, g: List[int], s: List[int]) -> int:g.sort()s.sort()m, n len(g), len(s)i j count 0while i < m and j < n:while j < n and g[i] > s[j]:j 1if j < n:count 1i …

uni-app - - - - -vue3使用i18n配置国际化语言

uni-app - - - - -使用i18n配置国际化语言 1. 安装vue-i18n2. 配置文件2.1 创建如下文件2.2 文件配置2.3 main文件导入i18n 3. 页面内使用3.1 template内直接使用3.2 变量接收使用 1. 安装vue-i18n npm install vue-i18n --save2. 配置文件 2.1 创建如下文件 locales文件夹里…

水泵模块(5V STM32)

目录 一、介绍 二、传感器原理 1.尺寸介绍 2.继电器控制水泵电路原理图 三、程序设计 main.c文件 bump.h文件 bump.c文件 四、实验效果 五、资料获取 项目分享 一、介绍 水泵模块(bump)通常是指用于液体输送系统的组件&#xff0c;它负责将水或其他流体从低处提…

四.网络层(上)

目录 4.1网络层功能概述 4.2 SDN基本概念 4.3 路由算法与路由协议 4.3.1什么是路由协议&#xff1f; 4.3.2什么是路由算法&#xff1f; 4.3.3路由算法分类 (1)静态路由算法 (2)动态路由算法 ①全局性 OSPF协议与链路状态算法 ②分散性 RIP协议与距离向量算法 4.3.…

【C语言】内存函数的使用和模拟实现

文章目录 一、memcpy的使用和模拟实现二、memmove的使用和模拟实现三、memset的使用四、memcmp的使用 一、memcpy的使用和模拟实现 在之前我们学习了使用和模拟实现strncpy函数&#xff0c;它是一个字符串函数&#xff0c;用来按照给定的字节个数来拷贝字符串&#xff0c;那么问…

【本地免费】SimpleTex 图像识别latex公式

文章目录 相关教程相关文献安装教程 由于mathpix开始收费了&#xff0c;于是本文将介绍一款目前本地免费的SimpleTex工具 相关教程 【超详细安装教程】LaTeX-OCR 图像识别latex公式&#xff08;开源免费&#xff09;_latex图片识别-CSDN博客 相关文献 SimpleTex主页——致力…

数据结构双向链表和循环链表

目录 一、循环链表二、双向链表三、循环双向链表 一、循环链表 循环链表就是首尾相接的的链表&#xff0c;就是尾节点的指针域指向头节点使整个链表形成一个循环&#xff0c;这就弥补了以前单链表无法在后面某个节点找到前面的节点&#xff0c;可以从任意一个节点找到目标节点…

5.3 克拉默法则、逆矩阵和体积

本节是使用代数而不是消元法来求解 A x b A\boldsymbol x\boldsymbol b Axb 和 A − 1 A^{-1} A−1。所有的公式都会除以 det ⁡ A \det A detA&#xff0c; A − 1 A^{-1} A−1 和 A − 1 b A^{-1}\boldsymbol b A−1b 中的每个元素都是一个行列式除以 A A A 的行列式。…

C(十一)scanf、getchar(第三弹)

问题引入&#xff1a;如何实现输入一串密码&#xff0c;如&#xff1a;“123 xxxx” &#xff0c;然后读取并确认&#xff0c;是 -- Y&#xff1b;否 -- N。 自然的&#xff0c;我们想到用scanf&#xff0c;但是在使用过程中你是否遇到跟我一样的困惑呢&#xff1f;如下&…

如何高效删除 MySQL 日志表中的历史数据?实战指南

在处理高并发的物联网平台或者其他日志密集型应用时&#xff0c;数据库中的日志表往往会迅速增长&#xff0c;数据量庞大到数百GB甚至更高&#xff0c;严重影响数据库性能。如何有效管理这些庞大的日志数据&#xff0c;特别是在不影响在线业务的情况下&#xff0c;成为了一项技…

【LeetCode HOT 100】详细题解之二叉树篇

【LeetCode HOT 100】详细题解之二叉树篇 94 二叉树的中序遍历方法一&#xff1a;递归方法二&#xff1a;迭代 104 二叉树的最大深度方法一&#xff1a;递归方法二&#xff1a;迭代 226 翻转二叉树方法一&#xff1a;递归方法二&#xff1a;迭代 101 对称二叉树方法一&#xff…

小程序-使用npm包

目录 Vant Weapp 安装 Vant 组件库 使用 Vant 组件 定制全局主题样式 API Promise化 1. 基于回调函数的异步 API 的缺点 2. 什么是 API Promise 化 3. 实现 API Promise 化 4.调用 Promise 化之后的异步 API 小程序对 npm 的支持与限制 目前&#xff0c;小程序中已经…

Java 之深入理解 String、StringBuilder、StringBuffer

前言 由于发现 String、StringBuilder、StringBuffer 面试的时候会经常问到&#xff0c;这里就顺便总结一下&#xff1a;本文重点会以这三个字符串类的性能、线程安全、存储结构这三个方面进行分析 ✨上期回顾&#xff1a;Java 哈希表 ✨目录 前言 String 介绍 String 的不可变…

全局安装cnpm并设置其使用淘宝镜像的仓库地址(地址最新版)

npm、cnpm和pnpm基本概念 首先介绍一下npm和cnpm是什么&#xff0c;顺便说一下pnpm。 npm npm&#xff08;Node Package Manager&#xff09;是Node.js的默认包管理器&#xff0c;用于安装、管理和分享JavaScript代码包。它是全球最大的开源库生态系统之一&#xff0c;提供了数…

如何使用ssm实现基于HTML的中国传统面食介绍网站的搭建+vue

TOC ssm758基于HTML的中国传统面食介绍网站的搭建vue 第1章 绪论 1.1选题动因 当前的网络技术&#xff0c;软件技术等都具备成熟的理论基础&#xff0c;市场上也出现各种技术开发的软件&#xff0c;这些软件都被用于各个领域&#xff0c;包括生活和工作的领域。随着电脑和笔…

微服务SpringGateway解析部署使用全流程

官网地址&#xff1a; Spring Cloud Gateway 目录 1、SpringGateway简介 1、什么是网关 2、为什么用网关【为了转发】 2、应用&#xff1a; 1.启动nacos 2.创建网关项目 3.网关配置1 4.网关配置2【了解】 5.过滤器配置【了解】 1、SpringGateway简介 核心功能有三个&…