专业的编程技术博客社区

网站首页 > 博客文章 正文

什么是Protobuf 序列化协议(protobuf详解)

baijin 2024-08-27 11:08:16 博客文章 5 ℃ 0 评论

Protocol Buffers(Protobuf)是 Google 开发的一种高效、灵活的数据序列化协议。可以简化数据交换和存储过程,并且具有很高的性能。它主要用于将结构化数据转换为紧凑的二进制格式,适合在网络中传输和存储。以下是 Protobuf 序列化协议的详细介绍:

1.基本概念

  • 消息(Message):Protobuf 数据的基本单位。消息由一组字段组成,每个字段都有一个唯一的标识符和类型。
  • 字段(Field):消息的组成部分。每个字段有一个标签(标签号)和类型(如整数、浮点数、字符串等)。

2.定义协议文件

Protobuf 使用 .proto 文件来定义数据结构。这个文件指定了消息的格式,包括字段名、字段类型和字段编号。

首先,创建一个名为 person.proto 的文件,定义数据结构,以下是一个简单的 .proto 文件示例:

syntax = "proto3"; // 指定语法版本

message Person {
  string name = 1; // 字段名称和编号
  int32 id = 2;
  string email = 3;
}

在这个示例中,定义了一个名为 Person 的消息,其中包含三个字段:name、id 和 email,它们分别有唯一的标签号 1、2 和 3。

3.编译协议文件

Protobuf 提供了一个编译器 protoc,用于将 .proto 文件转换成目标编程语言的代码。例如,将 .proto 文件编译成 Python、Java、C++ 或 Go 的类或结构体代码。

编译命令类似于:

protoc --python_out=. person.proto

这将生成一个 Python 文件,其中包含用于序列化和反序列化 Person 消息的类。

protoc --java_out=. person.proto

这会生成一个 PersonOuterClass.java 文件,包含用于序列化和反序列化的 Java 类。

4.序列化和反序列化

  • 序列化(Serialization):将消息对象转换为二进制格式。这使得数据可以高效地存储或传输。
  • 反序列化(Deserialization):将二进制格式的数据转换回消息对象,以便进行处理。

Python 示例,演示了如何使用生成的类进行序列化和反序列化:

import person_pb2  # 由 protoc 生成的 Python 文件

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

# 序列化
serialized_person = person.SerializeToString()

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

print(new_person)

JAVA示例,演示了如何使用生成的类进行序列化和反序列化:

//序列化
import com.example.PersonOuterClass.Person;
import java.io.FileOutputStream;
import java.io.IOException;

public class SerializeExample {
    public static void main(String[] args) {
        // 创建 Person 对象
        Person person = Person.newBuilder()
                .setName("Alice")
                .setId(123)
                .setEmail("alice@example.com")
                .build();
        
        // 序列化到文件
        try (FileOutputStream output = new FileOutputStream("person.ser")) {
            person.writeTo(output);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

//反序列化
import com.example.PersonOuterClass.Person;
import java.io.FileInputStream;
import java.io.IOException;

public class DeserializeExample {
    public static void main(String[] args) {
        // 从文件反序列化
        try (FileInputStream input = new FileInputStream("person.ser")) {
            Person person = Person.parseFrom(input);
            System.out.println("Name: " + person.getName());
            System.out.println("ID: " + person.getId());
            System.out.println("Email: " + person.getEmail());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

在这个示例中,我们创建了一个 Person 对象,序列化到一个文件,然后读取该文件并反序列化回 Person 对象。确保将 com.example 替换为实际的包名。

5.特性与优点

  • 高效:Protobuf 的二进制格式比 JSON 或 XML 更紧凑,数据传输和存储都更高效。
  • 跨平台:支持多种编程语言,数据可以在不同平台和语言之间轻松交换。
  • 版本兼容:允许在不破坏向后兼容性的情况下添加新字段或修改现有字段。

6.使用场景

  • 网络协议:用于定义和交换网络协议中的数据结构。
  • 数据存储:用于高效地存储和读取数据。
  • 远程过程调用(RPC):在分布式系统中用于定义和传输 RPC 调用的数据。

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表