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

news/2024/9/24 22:52:14/

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.ppmy.cn/news/1530000.html

相关文章

【Java】关键字-abstract【主线学习笔记】

文章目录 前言关键字-abstract的使用abstract修饰类:抽象类abstract修饰方法:抽象方法abstract不能修饰的结构 前言 Java是一门功能强大且广泛应用的编程语言,具有跨平台性和高效的执行速度,广受开发者喜爱。在接下来的学习过程中…

rust一些通用编程的概念

rust一些通用编程的概念 官网文档数据类型 - Rust 程序设计语言 中文版 (rustwiki.org) 变量,数据类型,条件判断,循环 变量 rust中变量的可变性是值得注意的 例如: fn main(){let number 1;number 2;println!("the number is {}&quo…

【C/C++语言系列】浅拷贝和深拷贝

浅拷贝和深拷贝在面试中经常被问,十分重要。 浅拷贝问题:如果有数据创建在堆区,那么在析构时会出现重复析构的问题。 解决方法:使用深拷贝去解决堆区数据重复释放的问题 观察下面代码,发现浅拷贝问题: cla…

python 实现collatz sequence考拉兹序列算法

collatz sequence考拉兹序列算法介绍 考拉兹序列(Collatz sequence),也被称为3n1序列或奇偶归一猜想(3x1 problem),是一个数学中的未解问题,由德国数学家Lothar Collatz在1937年提出。 考拉兹…

9.20-使用k8s部署wordpress项目

部署wordpress项目 部署mariadb # 启动docker进程systemctl start docker​# 拉取三个镜像​docker pull nginx:alpinedocker pull wordpress:latestdocker pull mariadb:latest​# 保存三个镜像​cddocker save -o wordpress.tar wordpress:latestdocker save -o mariadb.tar…

【数据结构初阶】链式二叉树接口实现超详解

文章目录 1. 节点定义2. 前中后序遍历2. 1 遍历规则2. 2 遍历实现2. 3 结点个数2. 3. 1 二叉树节点个数2. 3. 2 二叉树叶子节点个数2. 3. 3 二叉树第k层节点个数 2. 4 二叉树查找值为x的节点2. 5 二叉树层序遍历2. 6 判断二叉树是否是完全二叉树 3. 二叉树性质 1. 节点定义 用…

virtualbox中的网络模式,网络设置,固定IP

virtualbox关于网络设置的文档:https://www.virtualbox.org/manual/topics/networkingdetails.html#networkingdetails DHCP Dynamic Host Configuration Protocol:动态主机配置协议,是专门用来给网络中的节点分发IP地址,确保每…

【个人博客hexo版】hexo安装时会出现的一些问题

项目场景: 项目场景:在完成了GitHub仓库和git的连接之后,就要新建一个文件夹(例如hexo blog)进行下一步hexo的使用 问题描述 例如:如图所示 原因分析: 这些error不用看它到底是什么&#xf…