protobuf学习日记 | 初识protobuf

目录

前言

一、序列化与反序列化

二、protobuf是什么

三、protobuf的使用特点

四、快速上手

1、proto文件编写

2、编译proto文件

3、序列化与反序列化的使用


前言

        这是小编新开的一个栏目,为了记录自己在学习ProtoBuf的历程,也希望能帮助大家,本栏目主要以一个通信录小项目的形式来学习protobuf,本文主要浅浅认识一下protobuf是什么?以及我们如何使用protobuf,并没有进阶内容,只是作为一个新手初步了解protobuf的过程;

一、序列化与反序列化

        在学习protobuf之前,大家都先得清楚一个概念,就是序列化与反序列化,这与我们接下来为什么学习protobuf有很大的关系;

序列化:把对象转换为字节序列的过程称为对象的序列化。

反序列化:把字节序列恢复为对象的过程称为对象的反序列化。

应用场景:想必大家一定学习过网络编程吧?我们都知道,在进行网络传输过程中,我们一般不能传结构体,我们一般都传字符串等按字节为单位的数据,这是由于网络传输是跨主机的,不同主机可能出现不同的操作系统等不同标准,我们也听过一个概念就是大小端的概念,不同设备之间的标准也不同,若A主机按大端的方式将结构体传送给B主机,而B主机恰好为小端机器,那么这两者传输的数据就会出现异常,此时网络上就出现了网络字节序的概念,网络上的数据统一为大端,那么还有可能出现结构体对齐的问题,不同机器结构体对齐的标准也不同,因此就需要我们将数据进行序列化后再发送,接收端接收后,先进行反序列化得到结果;

二、protobuf是什么

        我们直接看官网对其进行的解释,如下所示;protobuf官网链接

翻译:

        Protocol Buffers是 Google 的⼀种语⾔⽆关、平台⽆关、可扩展的序列化结构数据的⽅法,它可⽤于(数据)通信协议、数据存储等。

        Protocol Buffers 类⽐于 XML,是⼀种灵活,⾼效,⾃动化机制的结构数据序列化⽅法,但是⽐  XML 更⼩、更快、更为简单。

        你可以定义数据的结构,然后使⽤特殊⽣成的源代码轻松的在各种数据流中使⽤各种语⾔进⾏编写和读取结构数据。你甚⾄可以更新数据结构,⽽不破坏由旧数据结构编译的已部署程序。

        简单来说,protobuf 就是一种让结构数据序列化的方法,关于翻译中的特点,我们在后面学习中慢慢体会;

三、protobuf的使用特点

        我们使用proto文件定义结构对象(message)及属性,然后通过proto编译器编译后生成结构体对象对应的方法,如序列化与反序列化,其实生成的就是两个文件,一个头文件,一个源文件,这两个文件可以被我们主业务逻辑使用,就像我们平常引入头文件一样,如下图所示;

        看完上面这个你可能还有点懵,不过没关系,下面我会进行使用演示,看完使用演示后,你会对上面这张图有更清晰的认识;

四、快速上手

        在这里,我打算尝试演示一遍protobuf的使用,这里我打算做一个通讯录1.0版本,我将会实现如下;

  • 对⼀个联系⼈的信息使⽤ PB(protobuf) 进⾏序列化,并将结果打印出来。
  • 对序列化后的内容使⽤ PB(protobuf) 进⾏反序列,解析出联系⼈信息并打印出来。
  • 联系⼈包含以下信息: 姓名、年龄。

1、proto文件编写

        下面为我们所接触第一个段protobuf代码,我会对代码进行一一解释,具体如下所示;

// 注释
/* 注释 */
syntax = "proto3";  // 这是指定我们使用proto版本
package contacts;    // 指定一个命名空间// 定义一个 message 结构
message PeopleInfo
{// 定义字段string name = 1;int32 age = 2;
}

(1)我们创建一个proto文件时,通常建议采用小写字母命名,且小写字母之间可以采用下划线分隔开来;如下所示

create_file

open_file

下图是我们这段代码的文件名

(2)注释有两种方法,如上述代码一二行,此注释方法与C语言、C++相同;

(3)我们使用关键字syntax来指定protobuf版本,这里一般指定proto3,若不写默认指定proto2;

(4)我们使用关键字package来指定一个命名空间,类似C++中的namespace,该命名空间作用于我们后续使用proto编译器编译该文件生成的文件代码作用域;

(5)我们使用关键字message来定义一个结构,其中结构中的字段用花括号括起来;

(6)我们定义的字段有不同的类型,上面分别为string类型与int32类型;每个字段都有一个字段编号,这个字段编号在该message中生效且唯一;(关于具体类型这里不做详细介绍,后面专门介绍)

(7)字段唯一编号我们推荐使用 15 3687 0911(2^29-1);其中范围1~15的字段我们进行编码需要一个字节,16~2047需要两个字节;这里的编码可理解成序列化;

2、编译proto文件

        我们通常使用如下命令进行编译proto文件;

protoc -I 要编译的proto文件所在目录   --cpp_out=生成文件所在目录   要编译的proto文件

        如上图我们编译完proto文件后,我指定的是当前目录,所以当前目录生成如下文件;

        没错,这些文件就是刚刚我们那个message结构对应的一些序列化、反序列化的方法;

3、序列化与反序列化的使用

        我们在上述目录下创建一个 mian.cc 的文件,保存我们接下来所编写主程序上的代码,如下所示,其中每一行都有注释;

// main.cc文件
#include <iostream>
#include <string>
#include "contacts.pb.h"int main()
{// 1、对⼀个联系⼈的信息使⽤PB进⾏序列化,并将结果打印出来。// 定义PeopleInfor结构体(PB根据我们的proto文件帮我们生成的)contacts::PeopleInfo people;people.set_name("张三");people.set_age(19);// 定义接收序列化后字符串的缓冲区std::string people_str;// 序列化bool ret = people.SerializeToString(&people_str);if(ret == false){std::cout << "序列化失败" << std::endl;exit(1);}printf("序列化成功,序列化后的结果为:\n%s", people_str.c_str());std::cout << "\n--------------------------- 分割线  ---------------------------\n";// 2、对序列化后的内容使⽤PB进⾏反序列,解析出联系⼈信息并打印出来。contacts::PeopleInfo destPeople;ret = destPeople.ParseFromString(people_str);if(ret == false){std::cout << "反序列化失败" << std::endl;exit(2);}std::cout << "反序列化成功,结果为: " << std::endl<< "name: " << destPeople.name() << std::endl<< "age: " << destPeople.age() << std::endl;return 0;
}

        上述中我们使用序列化,反序列化的接口都来自于我们编译proto文件后自动帮我们生成的代码;一般来说,我们获取一个类字段的值用我们一开始在proto文件中message中给字段取得名字来获取字段的值,如上述中的name和age,设置字段的值一种加一个set,对于序列化一般以Serialize为开头,反序列化一般以Parse为开头,这里我们作为初体验仅仅记住上述所陈述即可;

        对于上述代码,我们必须使用g++进行编译时,必须加上如下特定选项;

-std=c++11    // 这是因为我们的protobuf帮我们生成的代码中使用c++11

-lprotobuf       // 因为protobuf为第三方库,我们必须指定库名

        我们直接运行,如下所示;

        这时,我们会发现我们序列化后的结果是一行空行加一个张三,这是因为我们序列化后的结果为一串二进制序列,这里用string进行接收,所以打印时会出现乱码;

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

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

相关文章

亚马逊店飞飞ERP系统,跟卖+铺货+物流发货模式综合一体的ERP系统

跨境电商亚马逊&#xff0c;目前为止电商行业比较靠前的电商平台&#xff01;那么有人做电商&#xff0c;就会有人出单&#xff0c;有人出单就会有中转仓需求&#xff0c;代打包&#xff0c;代贴单&#xff01;那么这一切都是有一套逻辑完善的ERP来完成&#xff01;前端通过授权…

将.NET应用转换成Window服务

写在前面 本文介绍了将.NET8.0应用程序转换成Windows服务。 需要在NuGet中获取并安装&#xff1a;Microsoft.Extensions.Hosting.WindowsServices 包 代码实现 using System.Runtime.InteropServices; using WorkerService1;public class Program {public static void Main…

Kafka 简介

目录 1、概念介绍 Kafka 由来 ZooKeeper Kafka 特性 Kafka 使用场景 Kafka 复制备份 2、Kafka 架构 Broker Topic Producer Partition Consumers Consumer Group Distribution 1、概念介绍 Kafka 由来 Kafka 是最初由 Linkedin 公司开发&#xff0c;是一个分布…

aigc修复美颜学习笔记

目录 GFPGAN进行图像人脸修复 美颜 修复畸形手势 GFPGAN进行图像人脸修复 原文&#xff1a;本地使用GFPGAN进行图像人脸修复_人相修复处理网页 csdn-CSDN博客 人脸修复 1.下载项目和权重文件 2.部署环境 3.下载权重文件 4.运行代码 5.网页端体验 首先来看一下效果图 1.下…

uni-app的项目创建和环境搭建

uni-app 是一个使用 Vue.js 开发所有前端应用的框架&#xff0c;开发者编写一套代码&#xff0c;可发布到iOS、Android、Web&#xff08;响应式&#xff09;、以及各种小程序&#xff08;微信/支付宝/百度/头条/飞书/QQ/快手/钉钉/淘宝&#xff09;、快应用等多个平台。 第一步…

clip安装使用教程

1.配置环境 安装依赖 pip install transformers pip install torch 看缺失什么包自己先安装好 2.安装clip 进入https://github.com/openai/CLIP&#xff0c;先将CLIP文件夹下载到本地&#xff0c;随便什么位置。即点击下图中的Download ZIP&#xff0c;下载到本地后进行解压…

HNU-编译原理-实验2-Bison

编译原理实验2Bison 计科210X 甘晴void 202108010XXX 实验要求 详细的实验项目文档为 https://gitee.com/coderwym/cminus_compiler-2023-fall/tree/master/Documentations/lab2 实验步骤 本次实验需要在 Lab1 已完成的 flex 词法分析器的基础上&#xff0c;进一步使用 b…

某侠网js逆向wasm解析

本次目标地址如下&#xff0c;使用base64解密获得 aHR0cHM6Ly93d3cud2FpbWFveGlhLm5ldC9sb2dpbg 打开网址&#xff0c;本次的目标是登录接口&#xff0c;如下图 本文主要讲解wasm的解析&#xff0c;所以对其他参数不做逆向处理&#xff0c;本次由wasm加密的参数只有sign一个&a…

DApp:去中心化的革命与挑战

DApp&#xff08;去中心化应用&#xff09;是一种基于区块链技术的应用程序&#xff0c;与传统的中心化应用程序不同&#xff0c;DApp具有去中心化、透明、不可篡改等特性。本文将介绍DApp的前世今生&#xff0c;以及它的优势和未来发展。 DApp的前世可以追溯到区块链技术的出现…

运维工具之tmux命令

tmux终端复用器的使用 1.tmux的概念 ​ tmux&#xff0c;“Terminal MultipleXer”,意思是"终端复用器"。是一个可以让人们通过一个窗口操作多个会话的工具&#xff0c;对于经常操作Linux系统的运维人员来说&#xff0c;绝对是一款提高工作效率的利器。 2.tmux能帮…

Kubernetes API 和流量控制:管理请求数量和排队进程

本文描述了我们最近遇到的一个真实案例&#xff1a;Kubernetes API 因其中一个集群中的大量请求而瘫痪。今天&#xff0c;我们将讨论我们如何处理这个问题&#xff0c;并提供一些关于如何预防它的提示。 高并发搞崩 Kubernetes API 一个非常普通的早晨&#xff0c;我们开始了…

SSC | Blue Prism报告:2024年智能自动化(IA)7大趋势预测

近日&#xff0c;RPA行业领导者SS&C | Blue Prism发布《2024智能自动化&#xff08;IA&#xff09;趋势与预测》报告。报告中提到&#xff0c;智能自动化&#xff08;IA&#xff09;与流程管理的有效融合&#xff0c;是实现数字化转型成功的核心。采用业务流程管理&#xf…

免费开源OCR 软件Umi-OCR

Umi-OCR 是一款免费、开源、可批量的离线 OCR 软件&#xff0c;基于 PaddleOCR&#xff0c;适用于 Windows10/11 平台 免费&#xff1a;本项目所有代码开源&#xff0c;完全免费。方便&#xff1a;解压即用&#xff0c;离线运行&#xff0c;无需网络。高效&#xff1a;自带高效…

数组的定义与越界问题

scanf标准读取函数 第一个冷知识&#xff0c;输入到scanf里面的内容都是字符串形式&#xff0c;但是&#xff01; scanf(“%d”,&a),%d决定了如何对输入的字符串进行操作 scanf用来读取标准输入&#xff0c;标准输入的内容需要放入到某个变量空间中去&#xff0c;因此变量…

Python数据分析案例34——IMDB电影评论情感分析(Transformer)

电影评论的情感分析 案例背景 很多同学对电影系列的数据都比较喜欢&#xff0c;那我就补充一下这个最经典的文本分类数据集&#xff0c;电影情感评论分析。用神经网络做。对国外的英文评论文本进行分类&#xff0c;看是正面还是负面情感。 数据集介绍 数据集&#xff1a;IMDb…

Python Tkinter Pack布局管理器

GUI 编程就相当于小孩子搭积木&#xff0c;每个积木块应该放在哪里&#xff0c;每个积木块显示为多大&#xff0c;也就是对大小和位置都需要进行管理&#xff0c;而布局管理器正是负责管理各组件的大小和位置的。此外&#xff0c;当用户调整了窗口的大小之后&#xff0c;布局管…

sphinx,一个神奇的 Python 库!

更多资料获取 &#x1f4da; 个人网站&#xff1a;ipengtao.com 大家好&#xff0c;今天为大家分享一个神奇的 Python 库 - sphinx。 Github地址&#xff1a;https://github.com/sphinx-doc/sphinx/ 在软件开发和项目管理中&#xff0c;文档是不可或缺的一部分。好的文档可以…

企业工商年报在哪找?如何批量获取?

企业年报是什么&#xff1f;有什么用&#xff1f; 企业年报是企业每年必须向工商行政管理机关和税务机关报送的年度报告&#xff0c;是指公司整个会计年度的财务报告及其他相关文件。主要包括企业基本信息、资产负债表、利润表、现金流量表、股东及股本变化情况等内容。 作用…

SpringBoot集成p6spy

P6Spy 是一个可以用来在应用程序中拦截和修改数据操作语句的开源框架。 通过 P6Spy 我们可以对 SQL 语句进行拦截,相当于一个 SQL 语句的记录器,这样我们可以用它来作相关的分析,比如性能分析。这里主要用于在控制台打印SQL时能自动将问号替换成实际参数打印一个可执行的SQL…