Protocol Buffers(Protobuf)功能及使用方法
作者:old_power
Protocol Buffers(Protobuf) 是Google公司开发的一种数据描述语言,类似于XML能够将结构化数据序列化,可用于数据存储、通信协议等方面。protoc
是 Protocol Buffers(Protobuf) 的编译器,用于将 .proto
文件中定义的数据结构编译成目标编程语言的代码。Protocol Buffers 是 Google 开发的一种高效、跨语言的数据序列化格式,广泛用于通信协议、数据存储等领域。protoc
是使用 Protobuf 的核心工具。
1. Protocol Buffers 简介
Protocol Buffers 是一种二进制序列化格式,具有以下特点:
- 高效:比 XML 和 JSON 更小、更快。
- 跨语言:支持多种编程语言(如 C++, Java, Python, Go 等)。
- 可扩展:支持向后和向前兼容的字段更新。
- 结构化:通过
.proto
文件定义数据结构。
2. protoc 的功能
protoc
的主要功能是将 .proto
文件编译成目标语言的代码,生成的代码包括:
- 数据结构的类或结构体定义。
- 序列化和反序列化方法。
- 其他辅助方法(如字段访问、初始化等)。
3. .proto 文件
.proto
文件是 Protocol Buffers 的核心,用于定义数据结构和消息格式。以下是一个简单的 .proto
文件示例:
syntax = "proto3"; // 使用 proto3 语法 message Person { string name = 1; // 字段编号必须唯一 int32 id = 2; string email = 3; }
syntax
:指定使用的 Protobuf 语法版本(proto2
或proto3
)。message
:定义数据结构,类似于类或结构体。- 字段类型:如
string
、int32
、bool
等。 - 字段编号:每个字段的唯一标识符,用于二进制编码。
4. 使用 protoc 编译 .proto 文件
protoc
的基本命令格式如下:
protoc --<language>_out=<output_dir> <proto_file>
--<language>_out
:指定目标语言和输出目录。例如:--cpp_out
生成 C++ 代码。--java_out
生成 Java 代码。--python_out
生成 Python 代码。<output_dir>
:生成的代码的输出目录。<proto_file>
:输入的.proto
文件。
示例
假设有一个 example.proto
文件,生成 Python 代码:
protoc --python_out=. example.proto
这将生成 example_pb2.py
文件,供 Python 项目使用。
5. 支持的编程语言
protoc
支持多种编程语言,包括但不限于:
- C++
- Java
- Python
- Go
- JavaScript
- Ruby
- C#
- PHP
- Dart
- Kotlin
每种语言需要安装对应的 Protobuf 运行时库。
6. 安装protoc
在 Linux 上安装
使用包管理器安装:
sudo apt-get install protobuf-compiler # Ubuntu/Debian sudo yum install protobuf-compiler # CentOS/RHEL
在 macOS 上安装
使用 Homebrew 安装:
brew install protobuf
在 Windows 上安装
- 从 Protobuf 官方 GitHub 发布页面 下载预编译的
protoc
二进制文件。 - 解压并将
protoc
添加到系统环境变量中。
7. 常用命令选项
--cpp_out
:生成 C++ 代码。--java_out
:生成 Java 代码。--python_out
:生成 Python 代码。--go_out
:生成 Go 代码。--include_imports
:包含所有依赖的.proto
文件。--proto_path
:指定.proto
文件的搜索路径。
8. 示例:完整使用流程
步骤 1:定义 .proto
文件
创建 person.proto
文件:
syntax = "proto3"; message Person { string name = 1; int32 id = 2; string email = 3; }
步骤 2:编译 .proto
文件
生成 Python 代码:
protoc --python_out=. person.proto
执行 protoc --python_out=. person.proto
后,会生成 person_pb2.py
文件,内容类似于:
# Generated by the protocol buffer compiler. DO NOT EDIT! # source: person.proto import sys _b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) from google.protobuf import descriptor as _descriptor from google.protobuf import message as _message from google.protobuf import reflection as _reflection from google.protobuf import symbol_database as _symbol_database # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() class Person(_message.Message): __slots__ = ['name', 'id', 'email'] NAME_FIELD_NUMBER = 1 ID_FIELD_NUMBER = 2 EMAIL_FIELD_NUMBER = 3 ...
步骤 3:在 Python 中使用生成的代码
生成的 person_pb2.py
文件包含一个 Person
类,可以直接在 Python 代码中使用。
import person_pb2 # 导入生成的模块 # 创建一个 Person 对象 person = person_pb2.Person() person.name = "John Doe" person.id = 1234 person.email = "johndoe@example.com" # 序列化(将对象转换为二进制数据) serialized_data = person.SerializeToString() print("Serialized data:", serialized_data) # 反序列化(将二进制数据转换为对象) new_person = person_pb2.Person() new_person.ParseFromString(serialized_data) # 访问反序列化后的数据 print("Name:", new_person.name) print("ID:", new_person.id) print("Email:", new_person.email)
SerializeToString()
:将消息对象序列化为二进制字符串。ParseFromString(data)
:将二进制字符串反序列化为消息对象。- 字段访问:通过
.
操作符访问消息字段(如person.name
)。
运行结果
Serialized data: b'\n\x08John Doe\x10\xd2\t\x1a\x10johndoe@example.com'
Name: John Doe
ID: 1234
Email: johndoe@example.com
9. 高级功能
- 嵌套消息:在
message
中定义嵌套的message
。 - 枚举类型:定义枚举字段。
- Oneof:指定一组字段中只能有一个字段被设置。
- Map:定义键值对字段。
- RPC 服务:定义 gRPC 服务接口。
10. 总结
protoc
是 Protocol Buffers 的核心工具,用于将 .proto
文件编译成目标语言的代码。它支持多种编程语言,生成的代码高效且易于使用。通过 Protocol Buffers,开发者可以轻松实现跨语言的数据序列化和通信。
到此这篇关于Protocol Buffers(Protobuf)简介的文章就介绍到这了,更多相关Protocol Buffers Protobuf 简介内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!