Protobuf 原理大揭秘

本文介绍了Google的Protobuf数据存储格式,强调其高效性、跨语言支持和清晰的结构定义,同时探讨了其语法、原理解析以及使用建议,包括字段类型、编码方式、版本兼容性和性能优化技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、定义

Google推出的一种 结构化数据 的数据存储格式(类似于 XML、Json )。

多个版本的源码地址

https://github.com/protocolbuffers/protobuf/

1、为什么选择它

优点:

  1. 效率高:Protobuf 以二进制格式存储数据,比如 XML 和 JSON 等文本格式更紧凑,也更快。序列化和反序列化的速度也很快。
  2. 跨语言支持:Protobuf 支持多种编程语言,包括 C++、Java、Python、Objective、C、Ruby、Go、PHP、Dart、JavaScript(版本3.26)。
  3. 清晰的结构定义:使用 Protobuf,可以清晰地定义数据的结构,这有助于维护和理解。
  4. 向后兼容性:你可以添加或者删除字段,而不会破坏老的应用程序。这对于长期的项目来说是非常有价值的。

缺点:

  1. 不直观:由于 Protobuf 是二进制格式,人不能直接阅读和修改它。这对于调试和测试来说可能会有些困难。
  2. 缺乏一些数据类型:例如没有内建的日期、时间类型,对于这些类型的数据,需要手动转换成可以支持的类型,如 string 或 int。
  3. 需要额外的编译步骤:你需要先定义数据结构,然后使用 Protobuf 的编译器将其编译成目标语言的代码,这是一个额外的步骤,可能会影响开发流程。

2、语法

 Protobuf协议文件名后缀名为.proto。一个简单的Protobuf协议如下:

  1 syntax="proto3";
  2 
  3 package protobuf.addressbook;
  4 
  5 enum PhoneType
  6 {
  7   MOBILE = 0;
  8   HOME = 1;
  9   WORK = 2;
 10 }
 11 
 12 message Person
 13 {
 14   optional string name = 1;
 15   optional uint32 age = 2;
 16   optional string email = 3;
 17 
 18   message PhoneNumber
 19   {
 20     optional string number = 1;
 21     optional PhoneType type = 2;
 22   }
 23 
 24   repeated PhoneNumber phone = 4;                                                                                                                                                                                                      
 25                                            
 26 }                                          
 27                                            
 28                              
 29 message AddressBook          
 30 {                            
 31   repeated Person person = 1;
 32 }

必须指明版本:syntax = "proto3";

proto3比proto2的变化:

1、proto3比proto2支持跟多语言,语言增加 Go、Ruby、JavaNano 支持。

2、字段规则移除了"required",并把optional改名为了singlar,但是optional还可以用。

3、移除了 default 选项,在 proto2 中,可以使用 default 选项为某一字段指定默认值。在 proto3 中,字段的默认值只能根据字段类型由系统决定。也就是说,默认值全部是约定好的,而不再提供指定默认值的语法。

【在字段被设置为默认值的时候,该字段不会被序列化。这样可以节省空间,提高效率。但这样就无法区分某字段是根本没赋值,还是赋值了默认值。这在 proto3 中问题不大,但在 proto2 中会有问题。】

4、proto3默认采用 packed 编码,在 proto2 中,需要明确使用 [packed=true] 来为字段指定比较紧凑的 packed 编码方式。

5、枚举类型的第一个字段必须为 0。

6、移除了对分组的支持。

7、移除了对扩展的支持,新增了 Any 类型。proto3 中新增的 Any 类型有点像 C/C++ 中的 void* 。

8、增加了 JSON 映射特性。

 1)、标识符:

syntax:标识使用的protobuf是哪个版本。上面表示使用的是3.x版本。
package:标识生成目标文件的包名。在C++中表示的是命名空间。上面。表示生成的类和函数在protobuf命名空间的addressbook命令空间下。
enum:表示一个枚举类型。会在目标.h文件中自动生成一个枚举类型。
message:标识一条消息。会在目标文件中自动生成一个类。

2)、字段:

字段格式:role type name = tag [default value]

a、role有三种取值:

        required:该字段必须给值,不能为空。否则message被认为是未初始化的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

nmg10

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值