当前位置: 首页 > ds >正文

Google Protobuf初体验

在这里插入图片描述

前言

Google Protocol Buffers (Protobuf) 是一种语言中立、平台中立、可扩展的序列化结构数据格式,由 Google 开发。它用于将数据结构编码为二进制格式,以便在不同的服务之间高效地进行数据交换。Protobuf 的核心优势是其高效性(比 XML 和 JSON 更小、更快),以及跨语言支持(支持多种编程语言,如 Java、C++、Python、Go 等)。

Protobuf 的基本概念

  • 数据结构描述(Schema)Protobuf 使用 .proto 文件来描述数据结构。.proto 文件定义了消息类型、字段和字段的顺序。

  • 消息:消息是 Protobuf 中最基本的构造,类似于对象或结构体。消息由字段组成,每个字段都有一个唯一的编号和类型。

  • 序列化与反序列化Protobuf 将消息对象序列化为二进制数据,传输后接收端再将其反序列化为消息对象。

Protobuf 的基本使用

1. 定义 .proto 文件

Protobuf 的数据结构定义通过.proto文件来完成。每个 .proto 文件至少包含以下部分:

  • 语法声明:指定使用的 Protobuf 语法版本。

  • 消息定义:定义你要序列化的消息格式。

    syntax = "proto3";  // 使用 proto3 语法// 定义一个消息类型 Person
    message Person {string name = 1;     // 字段 name,类型为 string,编号为 1int32 id = 2;        // 字段 id,类型为 int32,编号为 2string email = 3;    // 字段 email,类型为 string,编号为 3
    }

    在这个示例中,Person 消息有三个字段:nameidemail,每个字段都有一个字段编号。Protobuf 使用字段编号来标识字段,而不是字段名称,这有助于在数据结构发生变化时保持兼容性。

2. 生成代码

定义完 .proto 文件后,你需要使用Protobuf 编译器 protoc生成对应的源代码,以便在代码中使用定义的消息。

编译命令

	protoc --java_out=./generated ./person.proto

这条命令会从 person.proto 文件中生成 Java 类 Person,你可以在 Java 项目中使用它。

3. 在代码中使用 Protobuf

假设你已经使用 protoc 编译生成了 Java 类,可以按照以下方式使用:

  • 1. 创建消息对象并序列化

    import com.example.generated.PersonProtos.Person;
    import java.io.FileOutputStream;
    import java.io.IOException;public class ProtobufExample {public static void main(String[] args) throws IOException {// 创建一个 Person 对象Person person = Person.newBuilder().setName("Alice").setId(1234).setEmail("alice@example.com").build();// 将 Person 对象序列化为字节数组并写入文件try (FileOutputStream output = new FileOutputStream("person.data")) {person.writeTo(output);}}
    }
  • 2. 从字节数据反序列化

    import com.example.generated.PersonProtos.Person;
    import java.io.FileInputStream;
    import java.io.IOException;public class ProtobufExample {public static void main(String[] args) throws IOException {// 从文件中读取序列化的数据try (FileInputStream input = new FileInputStream("person.data")) {// 反序列化数据Person person = Person.parseFrom(input);System.out.println(person.getName());System.out.println(person.getId());System.out.println(person.getEmail());}}
    }

Protobuf 的主要特性

  • 高效性:Protobuf 使用紧凑的二进制格式,比 JSON 或 XML 更小、更高效,适合在带宽有限或高性能要求的场合使用。

  • 跨语言支持:Protobuf 支持多种编程语言(Java、C++、Python、Go、C#、JavaScript 等),可以在不同平台之间进行无缝通信。

  • 可扩展性:可以随时为已有的消息格式添加新的字段,而不会破坏旧的字段和接口,支持向前和向后兼容。

  • 支持嵌套消息和集合:你可以在消息中嵌套其他消息,也可以定义集合(如数组、列表、字典等)。

    message AddressBook {repeated Person people = 1;  // 多个 Person 对象
    }
  • 支持枚举和高级类型:Protobuf 支持枚举类型,可以帮助表示有固定值集的字段。

    enum PhoneType {MOBILE = 0;HOME = 1;WORK = 2;
    }message PhoneNumber {string number = 1;PhoneType type = 2;
    }

使用 Protobuf 的场景

  • 微服务通信:Protobuf 特别适合微服务架构中服务间的高效通信,因为它比 JSON 或 XML 更紧凑且序列化速度更快。
  • RPC 系统:Protobuf 是 gRPC(Google 的开源 RPC 框架)的默认数据格式,它支持高效、跨语言的远程过程调用。
  • 存储数据:Protobuf 可以用作二进制数据存储格式,适用于日志系统、数据库序列化等场景。
  • 移动设备和 IoT:由于其高效性,Protobuf 非常适合带宽受限和处理能力有限的移动设备或物联网(IoT)设备。

与其他格式对比

特性JSONXMLProtobuf
可读性良好良好二进制格式,不易读
数据大小较大非常大非常小
序列化速度较慢非常慢非常快
跨语言支持支持大部分语言支持大部分语言支持大部分语言
可扩展性支持支持支持

小结

Protobuf 是一种高效、跨平台、可扩展的数据序列化框架,适合在需要高效数据交换和存储的场景下使用。通过 .proto 文件定义数据结构,结合编译器生成的代码,可以轻松地进行数据的序列化和反序列化。

源码当中的使用

在这里插入图片描述

http://www.xdnf.cn/news/19412.html

相关文章:

  • 深层语义在自然语言处理中的理论框架与技术融合研究
  • 使用电脑操作Android11手机,连接步骤
  • Python爬虫实战:研究统计学方法,构建电商平台数据分析系统
  • 面经分享--小米Java一面
  • 具有类人先验知识的 Affordance-觉察机器人灵巧抓取
  • STM32 之GP2Y1014AU0F的应用--基于RTOS的环境
  • 老题新解|不与最大数相同的数字之和
  • PCB 局部厚铜工艺:技术升级与新兴场景应用,猎板加工亮点
  • 同步/异步日志库
  • 响应式编程框架Reactor【4】
  • Web 聊天室消息加解密方案详解
  • open webui源码分析13-模型管理
  • 数据结构--栈(Stack) 队列(Queue)
  • Python API接口实战指南:从入门到精通
  • Linux查看有线网卡和无线网卡详解
  • 【Linux】基础I/O和文件系统
  • 初学者如何学习项目管理
  • 计算机毕设javayit商城 基于SSM框架的校园二手交易全流程管理系统设计与实现 Java+MySQL的校园二手商品交易与供需对接平台开发
  • 【嵌入式原理系列-第六篇】从Flash到RAM:MCU ld脚本全解析
  • TuringComplete游戏攻略(一、基础逻辑电路)
  • Python Facebook Logo
  • 神经网络正则化三重奏:Weight Decay, Dropout, 和LayerNorm
  • ARM 裸机开发 知识点
  • 豌豆压缩怎么用?3步避免网盘资源被和谐 网盘压缩包总被和谐?豌豆压缩实测解析 豌豆压缩避坑指南:敏感资源存储必读
  • 雷卯国产化之SE3401完全替代AOS的AO3401
  • 数字签名 digital signature
  • 年化225%,回撤9%,夏普4.32,3积分可查看参数
  • Java 常见异常系列:ClassNotFoundException 类找不到
  • Java 学习笔记(基础篇12)
  • 学习Python中Selenium模块的基本用法(10:浏览器操作)