2024 年最新 Protobuf 结构化数据序列化和反序列化详细教程

Protobuf 序列化概述

Protobuf(Protocol Buffers)是由Google开发的一种语言中立、平台中立、可扩展的序列化结构数据的方法。它用于在不同系统之间高效地交换数据。Protobuf使用定义文件(.proto)来描述数据结构,并通过编译生成特定语言的代码。它的优点包括小巧的二进制格式、高效的序列化速度和向后兼容性,非常适合需要高性能和跨语言的应用场景。

在这里插入图片描述

常见序列化格式

序列化格式描述优点缺点适用场景
JSON一种轻量级的数据交换格式,使用文本表示,基于键值对。可读性好,跨平台、跨语言支持广泛,解析库多体积较大,性能较低(相较于二进制格式)Web应用,API通信
XML类似HTML的标记语言,用于表示结构化数据。结构化良好,支持复杂的数据类型冗余较大,体积大,解析速度慢早期Web服务,严格的数据验证
ProtobufGoogle开发的二进制序列化格式,高效、语言中立。高效的二进制格式,传输速度快,向后兼容性好不可读,需定义.proto文件并编译高性能系统,服务间通信(gRPC)
AvroApache开发的序列化格式,适合大数据处理。数据描述和数据一起存储,支持丰富的数据类型需要架构支持,工具复杂度高大数据处理,Hadoop和Kafka环境
MessagePack一种高效的二进制序列化格式,比JSON更紧凑。二进制格式更紧凑,解析速度快人类不可读,调试较难网络通信,资源受限环境

序列化(Serialization)

序列化是指将对象或数据结构转换成一种可以保存到文件或传输到网络上的格式的过程。这种格式通常是二进制或文本格式,便于传输或存储。通过序列化,复杂的数据结构(如对象、数组、字典等)可以被转换为线性的字节流。

序列化作用

持久化存储:数据可以被序列化后保存到磁盘,供将来使用。
数据传输:序列化后的数据可以在网络上传输,便于不同的计算机或进程间交换数据。
跨语言交互:通过中立的序列化协议(如Protobuf、JSON、XML),不同编程语言之间可以交换数据。

反序列化(Deserialization)

反序列化是序列化的逆过程,它将字节流或文件恢复为原始的对象或数据结构。通过反序列化,接收到的或读取的序列化数据可以重新恢复成在发送端的对象格式。

反序列化作用

数据恢复:可以从磁盘、数据库或网络中读取序列化的数据并恢复为内存中的数据结构。
跨语言兼容性:接收到的序列化数据可以通过反序列化恢复成接收端系统中相应的结构。

.proto文件用于定义Protobuf的消息结构,它通过声明消息类型、字段、枚举等内容,生成用于序列化和反序列化的代码。以下是Protobuf的.proto文件语法格式的基本构成和示例。

proto 基本语法

syntax:指定 Protobuf 的语法版本,常用的是 proto3。Protobuf 的语法版本主要分为两个版本:proto2 和 proto3。它们在功能和约束上有所不同,proto3 是 proto2 的简化和改进版本。

syntax = "proto3";

package:用于在 .proto 文件中定义消息所在的包名,类似于编程语言中的命名空间(namespace)。它可以帮助在生成代码时避免命名冲突,并组织和管理生成的代码结构。

在 Protobuf 编译器生成的代码中,package 会影响生成文件的路径或命名。例如在 Java 中 package 会映射到相应的包结构。在 Python 中它可以影响模块导入的结构。

package mypackage;

import:在 Protobuf 中,import 允许你在一个 .proto 文件中引用和使用其他 .proto 文件定义的消息、枚举或服务。这在大型项目中非常有用,可以将不同的消息定义拆分成多个文件,从而更好地组织和管理代码。

import "other.proto";

message:定义一个消息类型(相当于面向对象编程中的类)。在 Protobuf 中,message 用于定义一个消息类型(类似于面向对象编程中的类),它表示一种结构化数据格式。每个 message 包含一组字段,每个字段有一个类型、名称和唯一的标识符(tag),用于标记在序列化和反序列化过程中字段的顺序。

message MyMessage {int32 id = 1;string name = 2;
}

Protobuf 字段类型

标量类型:Protobuf支持多种基本数据类型,例如 `int32`, `int64`, `float`, `double`, `bool`, `string`, `bytes`等。
repeated:表示字段可以重复,类似于数组或列表。
自定义类型:可以引用其他消息类型或枚举类型。

enum:定义枚举类型。在 Protobuf 中,enum 用于定义枚举类型,它表示一组固定的常量值。每个枚举值都有一个唯一的名称和对应的整数值,整数值通常从 0 开始递增。enum 类似于其他编程语言中的枚举类型,常用于表示状态、类型、选项等离散的固定值集合。

enum Status {UNKNOWN = 0;STARTED = 1;COMPLETED = 2;
}

service:定义服务和RPC方法(主要用于gRPC)。服务是逻辑上的一组功能或操作,定义了客户端和服务器之间的接口。在 gRPC 中,服务使用 service 关键字定义。一个服务可以包含多个 RPC 方法。

RPC 方法是服务中的具体操作,描述了客户端如何请求服务器执行某项任务。每个 RPC 方法都有输入消息和输出消息。输入消息定义了客户端发送给服务器的数据结构。输出消息定义了服务器返回给客户端的数据结构。

service MyService {rpc GetUser (UserRequest) returns (UserResponse);
}
RPC 方法:输入消息
message UserRequest {int32 user_id = 1;
}
RPC 方法:输出消息
message UserResponse {string name = 1;string email = 2;
}

tag:每个字段都有一个唯一的 tag,用于在序列化时识别字段,范围为 12^29 - 1

proto 常见字段类型

类型说明
int3232位整型
int6464位整型
float32位浮点数
double64位浮点数
bool布尔型
string字符串
bytes二进制数据
repeated重复字段,相当于数组或列表

proto3 案例

syntax = "proto3";package example;enum TaskStatus {PENDING = 0;IN_PROGRESS = 1;DONE = 2;
}message Task {int32 id = 1;string description = 2;TaskStatus status = 3;repeated string labels = 4;   // 标签数组
}service TaskService {rpc CreateTask(Task) returns (Task);rpc GetTask(Task) returns (Task);
}

编译 .proto 文件

使用 Protobuf 编译器(protoc)可以生成目标语言的代码(例如 C++、Python、Java)。编译后会生成相应语言的类,用于序列化和反序列化定义的消息。

protoc --python_out=. yourfile.proto

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

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

相关文章

HTML5+JavaScript绘制闪烁的网格错觉

HTML5JavaScript绘制闪烁的网格错觉 闪烁的网格错觉(scintillating grid illusion)是一种视觉错觉,通过简单的黑白方格网格和少量的精心设计,能够使人眼前出现动态变化的效果。 闪烁的栅格错觉,是一种经典的视觉错觉…

GreenPlum数开手册【语法篇】

GreenPlum数开手册 一、数据类型 1、基本数据类型 类型长度描述范围bigint8字节大范围整数-9223372036854775808 到 9223372036854775807smallint2字节小范围整数-32768到32767integer(int)4字节常用整数-2147483648 到 2147483647decimal可变长用户指定的精度,精…

Android手机投屏方案实现方式对比

文章目录 1.概述2.术语解释2.1 miracast2.2 scrcpy2.4 Wifi Direct2.5 app_process 3.技术实现对比3.1 Miracast3.1.1 Miracast介绍3.1.2 Miracast原理3.1.3 Miracast优缺点分析 3.2 Scrcpy3.2.1 scrcpy 介绍3.2.2 scrcpy的实现原理3.2.3 scrcpy的优缺点分析 3.3 Google cast3.…

在IDEA中构建Jar包,安装Jar包到Maven仓库并在Maven项目中使用

文章目录 0. 关于本文1. IDEA构建Jar包1.1 准备一份Java代码(就是你要构建工件的代码)1.2 进行如下步骤构建工件 2. 关于Maven3. 将Jar包安装到Maven仓库4. 使用安装的Jar包依赖 0. 关于本文 本文内容: 借助IDEA构建Jar包将Jar包安装到Mave…

青动CRM V3.2.1

全面解决企业销售团队的全流程客户服务难题旨在助力企业销售全流程精细化、数字化管理,全面解决企业销售团队的全流程客户服务难题,帮助企业有效盘活客户资源、量化销售行为,合理配置资源、建立科学销售体系,提升销售业绩。标准授…

shell脚本使用==判断相等报错

文章目录 方法 1:使用 比较符方法 2:强制使用 bash 这个错误的原因是你使用了 比较符,而 /bin/sh (或一些系统的默认 sh 解释器) 可能不支持它。对于 POSIX 兼容的 shell(如 /bin/sh),应该使用单个等号…

LeetCode[简单] 136. 只出现一次的数字

给你一个 非空 整数数组 nums ,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。 你必须设计并实现线性时间复杂度的算法来解决此问题,且该算法只使用常量额外空间。 思路 当 A 与 B 不同时,按…

2024CSCO 芦康沙妥珠单抗创造晚期TNBC二线治疗新高度

前言 “魔法子弹”的概念从上世纪初提出,经过一百多年的不断探索,抗体药物偶联物(ADC)从理想照进现实,达到今天百舸争流的盛况,被认为是极具前景的创新疗法,全球范围内已有十余款产品被批准用于…

友元运算符重载函数

目录 1.定义友元运算符重载函数的语法形式 2.双目运算符重载 3.单目运算符重载 1.定义友元运算符重载函数的语法形式 (1)在类的内部,定义友元运算符重载函数的格式如下: friend 函数类型 operator 运算符(形参表&a…

开源标注工具

DoTAT https://github.com/FXLP/MarkTool 后端代码未开放,可能有数据泄露风险 Chinese-Annotator https://github.com/deepwel/Chinese-Annotator 安装非常麻烦,github更新频率比较低,支持功能和doccano类似 IEPY https://github.com/ma…

国庆假节高速免费通行全攻略

关注▲洋洋科创星球▲一起成长! 国庆节假期全国收费公路继续对7座以下(含7座)小型客车免收车辆通行费。 具体免费时段从 10月1日00:00开始 10月7日24:00结束 01 提前出发,免费离开: 如果你在…

Win10系统使用mstsc远程电脑的时候发现隔一段时间就无法使用剪贴板_rdpclip---Windows运维工作笔记055

最近在使用温湿系统的远程桌面功能的时候发现,每当使用一段时间的时候,这个时候远程桌面功能的粘贴板就没办法使用了。 正常情况下,不管我一个电脑远程了多少台电脑,那么这些电脑之间都是可以使用粘贴板的,可以用来从一个电脑中截了图,然后粘贴到另一个电脑中。 但是现…

HuggingChat macOS 版现已发布

Hugging Face 的开源聊天应用程序 Hugging Chat,现已推出适用于 macOS 的版本。 主要特点 Hugging Chat macOS 版本具有以下亮点: 强大的模型支持: 用户可以一键访问多个顶尖的开源大语言模型,包括 Qwen 2.5 72B、Command R、Phi 3.5、Mistral 12B 等等&…

Mathematica线性优化-单纯形/改善单纯形/内点法

引言 Mathematica提供了多种工具和函数来实现线性优化,这些工具可以处理从简单的线性规划问题到复杂的多变量优化问题,最近运筹学作业要熟悉线性优化的编程方法,我们就使用mathematica进行:所有运行代码都在文章上面的资源中&…

【线程】线程池

线程池通过一个线程安全的阻塞任务队列加上一个或一个以上的线程实现,线程池中的线程可以从阻塞队列中获取任务进行任务处理,当线程都处于繁忙状态时可以将任务加入阻塞队列中,等到其它的线程空闲后进行处理。 线程池作用: 1.降…

MySQL 中的 FOREIGN KEY 约束:确保数据完整性的关键

在 MySQL 数据库中,FOREIGN KEY(外键)约束是一种非常重要的机制,它可以帮助我们确保数据的完整性和一致性。那么,FOREIGN KEY 约束究竟是什么呢?让我们一起来深入了解一下。 一、什么是 FOREIGN KEY 约束&…

帆软通过JavaScript注入sql,实现数据动态查询

将sql语句设置为参数 新建数据库查询 设置数据库查询的sql语句 添加控件 JavaScript实现sql注入 添加事件 编写JavaScript代码 //获取评价人id var pjrid this.options.form.getWidgetByName("id").getValue();//显示评价人id alert("评价人:&…

设计模式之策略设计模式

一、状态设计模式概念 策略模式(Strategy) 是一种行为设计模式, 它能让你定义一系列算法, 并将每种算法分别放入独立的类中, 以使算法的对象能够相互替换。 适用场景 当你想使用对象中各种不同的算法变体, …

Vue|插件

在 Vue.js 中,插件是用来扩展 Vue 功能的一种方式,能够帮助开发者扩展和复用功能。通过合理使用插件,可以提高代码的组织性和可维护性 目录 如何使用插件?插件的定义创建及使用插件插件的参数插件的扩展 总结 如何使用插件? 插件的定义 插…

iOS OC 底层原理之 category、load、initialize

文章目录 category底层结构runtime 执行 category 底层原理添加成员变量 load调用形式系统调用形式的内部原理源码实现逻辑 initialize调用形式源码核心函数(由上到下依次调用)如果分类实现了 initialize category 底层结构 本质是结构体。struct _cat…