ProtoBuf 入门教程

在网络通信和通用数据交换等应用场景中经常使用的技术是 JSON 或 XML,本教程介绍另外一个数据交换的协议的工具ProtoBuf。

快速入门

简介

protocol buffers (ProtoBuf)是一种语言无关、平台无关、可扩展的序列化结构数据的方法,它可用于(数据)通信协议、数据存储等。

Protocol Buffers 是一种灵活,高效,自动化机制的结构数据序列化方法-可类比 XML,但是比 XML 更小(3 ~ 10倍)、更快(20 ~ 100倍)、更为简单。

json\xml都是基于文本格式,protobuf是二进制格式。

你可以通过 ProtoBuf 定义数据结构,然后通过 ProtoBuf 工具生成各种语言版本的数据结构类库,用于操作 ProtoBuf 协议数据

本教程介绍的是最新的protobuf proto3版本的语法。

使用ProtoBuf的例子

创建 .proto 文件,定义数据结构

使用 ProtoBuf ,首先需要通过 ProtoBuf 语法定义数据结构(消息),这些定义好的数据结构保存在.proto为后缀的文件中。

例子:

文件名: response.proto

说明:proto文件中,字段后面的序号,不能重复,定义了就不能修改,可以理解成字段的唯一ID。

安装ProtoBuf编译器

protobuf的github发布地址: https://github.com/protocolbuffers/protobuf/releases

protobuf的编译器叫protoc,在上面的网址中找到最新版本的安装包,下载安装。

这里下载的是:protoc-3.9.1-win64.zip , windows 64位系统版本的编译器,下载后,解压到你想要的安装目录即可。

提示:安装完成后,将 [protoc安装目录]/bin 路径添加到PATH环境变量中

打开cmd,命令窗口执行protoc命令,没有报错的话,就已经安装成功。

将.proto文件,编译成指定语言类库

protoc编译器支持将proto文件编译成多种语言版本的代码,我们这里以java为例。

切换到proto文件所在的目录, 执行下面命令

然后在当前目录生成了一个ResponseOuterClass.java的java类文件,这个就是我们刚才用protobuf语法定义的数据结构对应的java类文件,通过这个类文件我们就可以操作定义的数据结构。

在代码中使用ProtoBuf对数据进行序列化和反序列化

因为上面的例子使用的是java, 我们先导入protobuf的基础类库。

maven:

使用ProtoBuf的例子。

消息(message),在protobuf中指的就是我们要定义的数据结构。

定义消息

语法

syntax关键词定义使用的是proto3语法版本,如果没有指定默认使用的是proto2。

message关键词,标记开始定义一个消息,消息体,用于定义各种字段类型。

提示: protobuf消息定义的语法结构,跟我们平时接触的各种语言的类定义,非常相似。

例子:

定义了一个SearchRequest消息,这个消息有3个字段,query是字符串类型,page_number和result_per_page是int32类型。

提示:我们通常将protobuf消息定义保存在.proto为后缀的文件中。

字段类型

支持多种数据类型,例如:string、int32、double、float等等,下一章节会有详细的讲解。

分配标识号

通过前面的例子,在消息定义中,每个字段后面都有一个唯一的数字,这个就是标识号。

这些标识号是用来在消息的二进制格式中识别各个字段的,一旦开始使用就不能够再改变,每个消息内唯一即可,不同的消息定义可以拥有相同的标识号。

注意:[1,15]之内的标识号在编码的时候会占用一个字节。[16,2047]之内的标识号则占用2个字节。所以应该为那些频繁出现的消息元素保留 [1,15]之内的标识号。切记:要为将来有可能添加的、频繁出现的字段预留一些标识号。

保留标识号(Reserved)
如果你想保留一些标识号,留给以后用,可以使用下面语法:

如果使用了这些保留的标识号,protocol buffer编译器会输出警告信息。

注释

往.proto文件添加注释,支持C/C++/java风格的双斜杠(//) 语法格式。

例子:

为消息定义包

我们也可以为消息定义包。

例子:

定义了一个包:foo.bar

选项

下面是一些常用的选项:

  • java_package
    单独为java定义包名字。
  • java_outer_classname
    单独为java定义,protobuf编译器生成的类名。

将消息编译成各种语言版本的类库

编译器命令格式:

OPTION是命令的选项, PROTO_FILES是我们要编译的proto消息定义文件,支持多个。

常用的OPTION选项:

例子:

在当前目录导出java版本的代码,编译demo.proto消息。

有些语言需要单独安装插件才能编译proto,例如golang

编译成go语言版本

数据类型

Protobuf定义了一套基本数据类型,下表罗列出了protobuf类型和其他语言类型的映射表。

ProtoBuf 入门教程

来自:https://www.tizi365.com/archives/374.html

枚举类型

当需要定义一个消息类型的时候,可能想为一个字段指定“预定义值序列”中的一个值,这时候可以通过枚举实现。

例子:

数组类型

在protobuf消息中定义数组类型,是通过在字段前面增加repeated关键词实现,标记当前字段是一个数组。

整数数组的例子:

字符串数组

消息嵌套

我们在各种语言开发中类的定义是可以互相嵌套的,也可以使用其他类作为自己的成员属性类型。

在protobuf中同样支持消息嵌套,可以在一个消息中嵌套另外一个消息,字段类型可以是另外一个消息类型。

引用其他消息类型的用法

消息嵌套

类似类嵌套一样,消息也可以嵌套。

例子:

import导入其他proto文件定义的消息

我们在开发一个项目的时候通常有很多消息定义,都写在一个proto文件,不方便维护,通常会将消息定义写在不同的proto文件中,在需要的时候可以通过import导入其他proto文件定义的消息。

例子:

保存文件: result.proto

保存文件: search_response.proto

map类型

protocol buffers支持map类型定义。

map语法

key_type可以是任何整数或字符串类型(除浮点类型和字节之外的任何标量类型)。请注意,枚举不是有效的key_type

value_type 可以是除另一个映射之外的任何类型。

map的例子

Map 字段不能使用repeated关键字修饰。

Golang 如何使用ProtoBuf

在go语言中,如何是用protobuf对数据进行序列化和反序列化。

安装protoc-gen-go

安装针对go语言的编译器插件。

安装好了之后, 在$GOPATH/bin下面会找到protoc-gen-go,编译器插件,将$GOPATH/bin路径添加到PATH环境变量中。

安装protobuf包

使用protobuf需要先安装对应的包。

定义proto消息

例子:

文件名:score_server/score_info.proto

编译proto文件,生成go代码

测试代码

本文为转载文章,贵在分享,版权归原作者及原出处所有,如涉及版权等问题,请及时与我联系。
原文出处:一架梯子,一头程序猿,仰望星空!
原文链接:https://www.tizi365.com/archives/386.html

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注