Protobuf编码和存储方式

protobuf的编码和存储方式

Protobuf 支持多种数据类型,如整数、浮点数、布尔值、字符串、字节数组、嵌套消息和枚举等。不同的数据类型在编码时有不同的规则。

整型的编码方式

Protobuf 对整数采用 Varint 编码,对于有符号的整数(如 sint32 和 sint64),Protobuf 使用 ZigZag 编码将负数转换为正数,这是可变长度整数编码的一种方式:

  1. Varint 使用一个或多个字节来表示,较小的整数使用较少的字节。
  2. 每个字节的最高位是继续位,如果设置为1,则表示后续还有字节;如果为0,则表示这是最后一个字节。
    Varint 编码避免了固定长度整数带来的额外空间浪费。

定长的编码方式

对于定长数据类型(如 fixed32 和 fixed64),Protobuf 使用固定的字节数进行编码:
fixed32:使用 4 个字节(32 位)。
fixed64:使用 8 个字节(64 位)。

字符串的编码方式

UTF-8 编码:

  1. Protobuf 强制要求字符串使用 UTF-8 编码。也就是说,字符串首先会被转换成 UTF-8 字节序列。
    例如,字符串 “Hello” 用 UTF-8 编码后是字节序列 [72, 101, 108, 108, 111] (每个字符转成一个字节)。
  2. 长度前缀变长整数编码(Varint 编码):
    在 Protobuf 中,所有长度字段都使用 Varint 编码。Varint 是一种可变长度的整数编码方式,用于有效地编码小整数。
  3. 字符串的长度首先被编码为 Varint。
    例如,“Hello” 的长度是 5,因此先编码 5,其 Varint 编码也是 [5]。
  4. 拼接结果:
    最终编码形式为 长度前缀 + UTF-8 字节序列。
    对于 “Hello”,整体编码结果是 [5, 72, 101, 108, 108, 111]。

存储方式

Protobuf 的数据结构由 .proto 文件定义,该文件描述了消息(Message)格式和字段(Field)。示例如下:

syntax = "proto3";

message Person {
  int32 id = 1;
  string name = 2;
  bool is_student = 3;
}
  1. message
    消息是数据结构的基本单元,每个消息包含一个或多个字段:
message Person {
  int32 id = 1;
  string name = 2;
  bool is_student = 3;
}
  1. 字段编码
    每个字段由字段编号和类型编码,紧随其后的数据值。字段编号与类型使用以下规则编码:

1)字段编号与类型合并成一个 Tag,用来标识字段。

2)Tag 的低 3 位表示字段类型,高位表示字段编号。

  1. 序列化过程
    序列化过程将 Protobuf 消息转换为二进制格式:

按字段定义的顺序编码各个字段及其数据值。

转换为紧凑的二进制格式后,可以高效地存储在文件中或通过网络传输。

  1. 反序列化

读取二进制数据,根据 Tag 确定字段编号和字段类型。

根据字段类型解码数据值,重建原始消息对象。

  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

for_forever_

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

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

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

打赏作者

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

抵扣说明:

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

余额充值