【Protobuf】xml、json与protobuf有什么区别,protobuf详解(保姆篇)

news2024/12/26 23:06:22

在这里插入图片描述

文章目录

    • 简介
    • Protobuf 的原理
    • 安装 Protobuf 编译器
    • 在 Python 中使用 Protobuf
      • 安装语言特定的 Protobuf 库
      • 定义消息结构
      • 生成代码
      • 使用 Protobuf 进行序列化和反序列化
    • 在 Java 中使用 Protobuf
      • 安装和配置
      • 编译 .proto 文件
      • 使用生成的 Java 类
        • 创建和序列化对象
      • 代码注释
    • 高级特性
      • 嵌套消息示例
      • 枚举示例
    • 性能优化和最佳实践
      • 性能优化
      • 最佳实践
    • xml、json与protobuf的区别
      • XML(可扩展标记语言)
      • JSON(JavaScript 对象表示法)
      • Protobuf(协议缓冲)
    • 更倾向于使用 XML 或 JSON 而非 Protobuf的原因

更多相关内容可查看


简介

Protocol Buffers(简称 Protobuf)是 Google 开发的一种语言中立、平台中立、可扩展的序列化结构数据的机制。它主要用于将数据结构序列化为二进制格式,以便于高效传输和存储。Protobuf 在性能、文件大小和数据兼容性方面有着显著的优势。


Protobuf 的原理

Protobuf 的基本工作原理是:

  1. 定义数据结构:通过 .proto 文件定义数据结构。
  2. 生成代码:使用 Protobuf 编译器将 .proto 文件编译为目标编程语言的类或结构体。
  3. 序列化:将定义好的数据结构序列化为二进制格式。
  4. 反序列化:将二进制数据反序列化为原始数据结构。

Protobuf 使用一种紧凑的二进制格式来表示数据,相较于 XML 和 JSON,Protobuf 的数据体积更小,解析速度更快。


安装 Protobuf 编译器

对于 Linux 和 macOS 用户,你可以通过包管理器进行安装:

# Ubuntu
sudo apt-get install protobuf-compiler

# macOS
brew install protobuf

对于 Windows 用户,你可以从 Protobuf 的 GitHub 页面 下载预编译的二进制文件并将其添加到 PATH 中。


在 Python 中使用 Protobuf

安装语言特定的 Protobuf 库

需要安装 protobuf 包:

pip install protobuf

定义消息结构

Protobuf 使用 .proto 文件定义数据结构。一个 .proto 文件可以包含多个消息(message),每个消息定义了一种数据结构。以下是一个简单的 .proto 文件示例:

示例:person.proto

syntax = "proto3";

// Person 是一个消息类型
message Person {
    // 字段编号是必须的,字段类型包括 string、int32、bool 等
    int32 id = 1; // 通过编号区分字段
    string name = 2;
    string email = 3;
}

// AddressBook 包含一个 Person 的列表
message AddressBook {
    repeated Person people = 1; // repeated 表示一个列表
}

注释:

  • syntax = "proto3";:指定使用 Protobuf 版本 3。Protobuf 3 是当前推荐的版本,简化了语法并提供了许多新的功能。
  • message:定义一个消息类型。在这里,PersonAddressBook 是消息类型。
  • int32string:字段类型。
  • = 1= 2:字段编号。Protobuf 使用这些编号在二进制格式中标识字段。
  • repeated:表示一个字段可以包含多个值,这里表示 people 是一个 Person 对象的列表。

生成代码

使用 protoc 编译器将 .proto 文件编译为目标语言的代码

protoc --python_out=. person.proto

该命令将生成 person_pb2.py 文件,其中包含了 Protobuf 定义的类和方法。--python_out 参数指定输出目录。

使用 Protobuf 进行序列化和反序列化

编写 Python 代码

import person_pb2  # 由 protoc 生成的 Python 文件

# 创建一个 Person 对象
person = person_pb2.Person()
person.id = 123
person.name = "Alice"
person.email = "alice@example.com"

# 序列化
data = person.SerializeToString()

print("Serialized data:", data)

# 反序列化
new_person = person_pb2.Person()
new_person.ParseFromString(data)

print("Deserialized person:")
print("ID:", new_person.id)
print("Name:", new_person.name)
print("Email:", new_person.email)

注释:

  • SerializeToString():将 Person 对象序列化为二进制格式。
  • ParseFromString(data):将二进制数据反序列化为 Person 对象。

运行

python your_script.py

在 Java 中使用 Protobuf

安装和配置

安装Protobuf 编译器 protoc 和 Java 的 Protobuf 库。可以从 Protobuf 官方网站 下载编译器,并通过 Maven 来管理 Java 的 Protobuf 依赖。

pom.xml 中添加 Protobuf 依赖:

<dependencies>
  <dependency>
    <groupId>com.google.protobuf</groupId>
    <artifactId>protobuf-java</artifactId>
    <version>3.21.12</version> <!-- 确保使用最新版本 -->
  </dependency>
</dependencies>

编译 .proto 文件

使用 protoc 工具将 .proto 文件编译为 Java 类。假设你的 .proto 文件名为 person.proto,可以使用如下命令:

protoc --java_out=src/main/java person.proto

这条命令会在 src/main/java 目录下生成 Java 源文件。这些源文件包含了序列化和反序列化所需的代码。

使用生成的 Java 类

编译后,你会得到一个 Java 类,例如 PersonProtos.Person

创建和序列化对象
import com.google.protobuf.InvalidProtocolBufferException;
import com.example.PersonProtos.Person; // 假设生成的类在 com.example 包下

public class ProtobufExample {

  public static void main(String[] args) {
    // 创建 Person 对象
    Person person = Person.newBuilder()
        .setId(1)
        .setName("Alice")
        .setEmail("alice@example.com")
        .addPhones("123-456-7890")
        .addPhones("098-765-4321")
        .build();

    // 序列化对象为字节数组
    byte[] data = person.toByteArray();

    // 反序列化字节数组为 Person 对象
    try {
      Person deserializedPerson = Person.parseFrom(data);
      System.out.println("ID: " + deserializedPerson.getId());
      System.out.println("Name: " + deserializedPerson.getName());
      System.out.println("Email: " + deserializedPerson.getEmail());
      System.out.println("Phones: " + deserializedPerson.getPhonesList());
    } catch (InvalidProtocolBufferException e) {
      e.printStackTrace();
    }
  }
}

代码注释

  • Person.newBuilder():创建一个新的 Person 构建器,用于设置字段值。
  • setId(1):设置 id 字段为 1
  • setName(“Alice”):设置 name 字段为 "Alice"
  • setEmail(“alice@example.com”):设置 email 字段为 "alice@example.com"
  • addPhones(“123-456-7890”):向 phones 列表添加一个电话号码。
  • build():构建 Person 对象。
  • toByteArray():将 Person 对象序列化为字节数组。
  • parseFrom(data):从字节数组中反序列化 Person 对象。

高级特性

Protobuf 还支持一些高级特性,比如嵌套消息、枚举类型和自定义选项等。

嵌套消息示例

message AddressBook {
  message Person {
    int32 id = 1;
    string name = 2;
  }
  repeated Person people = 1; // AddressBook 包含多个 Person
}

枚举示例

enum PhoneType {
  MOBILE = 0;
  HOME = 1;
  WORK = 2;
}

message Person {
  int32 id = 1;
  string name = 2;
  PhoneType phone_type = 3;
}

性能优化和最佳实践

性能优化

  • 使用 repeated 字段:当需要存储多个值时,使用 repeated 字段而不是嵌套消息,以减少不必要的嵌套层级。
  • 选择合适的数据类型:根据实际需要选择合适的数据类型。例如,对于大范围的整数,使用 int64 可能更合适。

最佳实践

  • 字段编号管理:确保在消息定义中字段编号唯一,并避免修改现有字段编号,以保持向后兼容性。
  • 文档和注释:在 .proto 文件中添加注释,帮助团队成员理解数据结构和字段含义。
  • 测试和验证:使用 Protobuf 提供的工具和测试框架进行验证,确保序列化和反序列化的准确性。

xml、json与protobuf的区别

在项目中选择使用 XML、JSON 还是 Protobuf 作为数据格式,通常取决于具体的需求。

XML(可扩展标记语言)

优点:

  • 自描述性强:XML 标签和属性使得数据的结构和语义更加清晰,便于人类阅读和理解。
  • 成熟的标准:XML 是一种成熟的标准,有大量的工具和库支持,包括用于验证和转换的 XSD(XML Schema Definition)。
  • 广泛的支持:许多旧系统和协议仍然使用 XML,特别是在企业应用中。

缺点:

  • 冗长:XML 通常比 JSON 和 Protobuf 更冗长,文件体积较大。
  • 处理复杂度:解析和处理 XML 可能会比较复杂,尤其是涉及到复杂的 XML Schema 时。

JSON(JavaScript 对象表示法)

优点:

  • 简洁:JSON 格式比 XML 更简洁,容易生成和解析。
  • 易于处理:与 JavaScript 兼容,使得在 Web 应用中非常流行。大多数编程语言都有原生或第三方库支持 JSON。
  • 可读性强:JSON 数据结构简单明了,易于人类阅读和理解。

缺点:

  • 不支持复杂的数据类型:JSON 对于某些复杂的数据结构(例如自定义类型)支持不如 XML 和 Protobuf。
  • 没有类型约束:JSON 是无类型的,不支持数据验证机制。

Protobuf(协议缓冲)

优点:

  • 高效:Protobuf 在序列化和反序列化方面非常高效,生成的二进制数据比 XML 和 JSON 更小,速度更快。
  • 强类型:Protobuf 使用定义良好的消息结构,并支持类型检查,减少了数据格式错误的可能性。
  • 版本管理:Protobuf 支持向前和向后兼容性,方便在版本升级时管理数据格式的变化。

缺点:

  • 人类可读性差:Protobuf 使用二进制格式,直接阅读和调试不如 XML 和 JSON 直观。
  • 复杂性:需要定义 .proto 文件和使用相应的编译器生成代码,增加了开发和维护的复杂度。
  • 工具和支持:虽然 Protobuf 已经被广泛接受,但某些老旧系统和工具可能不原生支持 Protobuf。

更倾向于使用 XML 或 JSON 而非 Protobuf的原因

  1. 可读性和调试:XML 和 JSON 都是文本格式,更易于人类阅读和调试。对于需要频繁手动检查数据的场景,XML 和 JSON 更加直观。

  2. 兼容性和支持:许多旧系统和企业应用依赖于 XML 或 JSON,并且已有大量的库和工具支持这些格式。在这种情况下,迁移到 Protobuf 可能会带来额外的复杂性和兼容性问题。

  3. 简单性和开发速度:JSON 特别适合 Web 开发,因为它可以很容易地与 JavaScript 交互,并且解析速度较快。对于较简单的数据交换,JSON 可能足够用且易于实现。

  4. 开发团队的熟悉度:如果开发团队对 XML 或 JSON 更加熟悉,使用这些格式可以减少学习成本和开发难度。

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

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

相关文章

LabVIEW灵活集成与调试的方法

在LabVIEW开发中&#xff0c;为了构建一个既便于调试又能灵活集成到主VI中的控制VI&#xff0c;开发者需要采用适当的编程方式和架构。常见的选择包括模块化设计、状态机架构以及事件驱动编程。这些方法有助于简化调试过程、提高系统的稳定性&#xff0c;并确保代码的重用性和可…

day43-测试平台搭建之前端vue学习-基础2

目录 一、数据代理 二、事件处理 三、计算属性 四、监控属性 五、绑定样式 六、今日学习思维导图 一、数据代理 1.1.数据代理&#xff1a;通过一个对象代理对另外一个对象中属性的操作 (读/写) 1.2.Vue中数据代理的好处&#xff1a;更加方便的操作data中的数据 1.3.基本原…

vue2结合element-ui使用tsx格式实现formily自定义组件

简洁 在公司实习&#xff0c;需要参与开发一个基于formily的低代码平台&#xff0c;实现自定义formily组件&#xff0c;在此记录一下。 示例源码 demo源码 实现思路 开始实现自定义组件之前最好先看一下formily官网的core、vue、element部分&#xff0c;如果有能力也可以阅…

2024数学建模国赛A题word版成品论文30页【附带完整解题代码+可视化图表】

0906 0:30 v1.0 问题一、问题二的完整可运行代码&#xff0c;模型建立与求解这一部分的论文。 0906 5:20 v1.1 增加了第三问的完整可运行代码和第二、三问的“模型建立与求解”的论文。&#xff08;即1-3问的代码、模型建立与求解、算法设计、结果分析&#xff09; 1-4问完整可…

TensorFlow创建回归神经网络及Optimizer优化器

一.TensorFlow创建神经层 如图所示&#xff0c;通过该神经网络识别动物猫或狗&#xff0c;共包括输入层&#xff08;Input Layer&#xff09;、隐藏层3层&#xff08;Hidden Layer&#xff09;和输出层&#xff08;Output Layer&#xff09;。其中每个隐藏层神经元都有一个激励…

Unity(2022.3.41LTS) - UI详细介绍- 原始图像

目录 零.简介 一、基本功能 二、属性和设置 三、与其他 UI 元素的配合 四、代码控制 六. 和 image的区别 零.简介 在 Unity 中&#xff0c;RawImage 是一种用于显示原始图像的 UI 组件。 一、基本功能 显示图像&#xff1a;RawImage 主要用于在 UI 中直接显示一张图像。…

Python数组遍历-从基础到高级的全面指南

你有没有想过,为什么有些程序员能够轻松地操纵大量数据,而其他人却在简单的数组操作上挣扎?答案往往藏在一个看似简单却至关重要的技能中:数组遍历。无论你是刚入门的新手,还是寻求提升的老手,掌握Python中的数组遍历技巧都将极大地提升你的编程效率和代码质量。 在这篇文章中…

使用 systemd-analyze 分析 Linux 系统启动慢的原因

使用 systemd-analyze 命令可以查看 Linux 系统在启动过程中每个服务的耗时情况, 方便我们排查是哪个环节导致系统启动缓慢, 以下是整理的常用命令参数和效果. 例子中一下子就可以定位到是 gssproxy.service 服务启动耗时过长. systemd-analyze blame Print list of running u…

LabVIEW如何自学成为专业开发者

自学成为LabVIEW专业开发者需要一个系统化的学习和实践过程&#xff0c;以下是一些关键步骤&#xff1a; 1. 扎实的基础学习 了解LabVIEW的基础概念&#xff1a;首先要熟悉LabVIEW的基本操作、数据流编程理念和图形化编程环境。可以通过LabVIEW的官方教程、Bilibili上的视频课程…

【舞动生命,不缺营养!】亨廷顿舞蹈症患者的维生素补给站

Hey小伙伴们~ &#x1f44b; 今天我们要聊的是一个温暖而重要的话题——关于亨廷顿舞蹈症&#xff08;HD&#xff09;患者如何通过合理补充维生素&#xff0c;来更好地支持他们的健康与生活品质&#xff01;&#x1f31f; &#x1f338; ‌首先&#xff0c;了解亨廷顿舞蹈症‌…

TCP的传输速度

如何确定TCP最大传输速度&#xff1f; TCP 的传输速度&#xff0c;受限于发送窗⼝&#xff0c;接收窗⼝以及⽹络设备传输能⼒。 其中&#xff0c;窗⼝⼤⼩由内核缓冲区⼤⼩决定。如果缓冲区与⽹络传输能⼒匹配&#xff0c;那么缓冲区的利⽤率就达到了最⼤化。 如何计算网络传…

JAVA:Spring Boot 整合 Swagger 的技术指南

请关注微信公众号&#xff1a;拾荒的小海螺 博客地址&#xff1a;http://lsk-ww.cn/ 1、简述 在现代Web开发中&#xff0c;API文档的生成和维护是非常重要的。Swagger是一款流行的API文档生成工具&#xff0c;它可以帮助开发者自动生成API文档&#xff0c;并提供可视化的接口…

Redis从简单使用到底层原理与分布式缓存

文章目录 [Redis参考手册](https://redis.io/docs/latest/commands/)1 基础认识1.1 安装配置1.2 通用命令1.3 数据类型1.3.1 数据结构与内部编码stringkey的结构hashlistsetsorted_set 1.4 单线程模型 2 redis客户端2.1 RESP协议&#xff08;Redis serialization protocol&…

SpringBoot2:请求处理原理分析-接口参数的常用注解

1、PathVariable 作用说明&#xff1a;获取路径参数 案例&#xff1a; 接口收参形式&#xff1a; GetMapping("/car/{id}/owner/{username}")public Map<String,Object> getCar(PathVariable("id") Integer id,PathVariable("username")…

echarts圆饼图定时器动画

(function () {const WdxjEcharts echarts.init(document.getElementById(wdxjEchart))let num 0;var imgURL "../imagesNew/wd-center.png";var trafficWay [{name: 火车,value: 20}, {name: 飞机,value: 10}, {name: 客车,value: 30}, {name: 轮渡,value: 40}]…

深入解读Docker核心网络管理:架构、模式与通信机制

在容器化技术中&#xff0c;网络管理是影响容器通信和应用部署的重要组成部分。Docker不仅简化了应用的部署过程&#xff0c;还提供了强大的网络管理功能&#xff0c;确保容器之间以及容器与外部系统的网络通信能够高效、稳定地进行。 本文将深入解读Docker的核心网络管理原理…

查看hprof文件

hprof可以用来分析某个进程的内存情况&#xff0c;对我们分析内存泄漏问题有很大帮助&#xff0c;本文主要记录如何生成及查看hprof文件。 1生成.hprof文件 可以使用adb命令生成 .hprof文件&#xff0c;生成的是在执行命令的那一刻&#xff0c;该进程的内存情况&#xff1a; …

后端Web之SpringBoot原理

目录 1.配置优先级 2.Bean 3.SpringBoot原理 1.配置优先级 SpringBoot中支持三种格式的配置文件: .application.properties、application.yml和application. yaml。它们的配置优先级分别降低。虽然springboot支持多种格式配置文件&#xff0c;但是在项目开发时,推荐统一使用…

视频智能分析平台LntonAIServer安防监控平台花屏检测、马赛克检测功能介绍

视频监控系统在现代社会中扮演着至关重要的角色&#xff0c;无论是用于安全监控、交通管理还是其他用途&#xff0c;视频的质量直接关系到系统的可靠性和有效性。LntonAIServer通过新增的视频质量诊断功能&#xff0c;包括花屏检测和马赛克检测&#xff0c;进一步增强了视频监控…

读书学习进阶笔记 # Datawhale X 李宏毅苹果书 AI夏令营

文章目录 &#x1f6a9;学习目标&#x1f6a9;学习内容&#x1f6a9; Task1.1&#x1f3af;为什么优化会失败&#x1f4cc;因非信息梯度导致的失败 &#x1f3af;局部极小值与鞍点&#x1f3af;临界点及其种类&#x1f3af;如何判断临界值种类&#x1f4cc;更简便的方法来判断 …