protobuf string类型_Protobuf

介绍

Google Protocol Buffer(简称Protobuf)是一种轻便、高效的结构化数据存储格式,平台无关、语言无关、可扩展、可用于通讯协议和数据存储等领域。

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

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

优势

序列化后体积比json和xml更小,适合网络传输

支持跨平台多语言

消息格式升级和兼容还不错

序列化和反序列化很快,快于json的处理速度

不足

功能简单,无法用来表示复杂概念。

通用性上不足。

不适合用来描述数据结构。

它以二进制方式存储,除非有.proto定义,否则没法直接读出protobuf的任何数据。

比较

说明

json

一般的web项目中,最流行的主要还是json。因为浏览器对于json数据支持非常友好,有很多内建的函数支持。

xml

在webservice中应用最为广泛,但是相比于json,它的数据更加冗余,因为需要成对的闭合标签。

protobuf

后起之秀,是google开源的一种数据格式,适合高性能、对响应速度有要求的数据传输场景。因为protobuf是二进制数据格式,需要编码和解码。数据本身不具有可读性。因此只能反序列化之后得到真正可读的数据。

安装

MacOS

CentOS

Ubuntu

12

> brew install protobuf

> protoc --version

12345678910111213141516171819

> yum -y install autoconf automake libtool make g++

> cd /usr/local/src/

> wget https://github.com/protocolbuffers/protobuf/releases/download/v3.12.0/protobuf-all-3.12.0.tar.gz

> tar zxvf protobuf-all-3.12.0.tar.gz

> cd protobuf-3.12.0/

> ./autogen.sh

> ./configure --prefix=/usr/local/protobuf

> make

> make check

> make install

> ldconfig

> vim /etc/profile

##### 增加如下内容 #####

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/protobuf/lib

export LIBRARY_PATH=$LIBRARY_PATH:/usr/local/protobuf/lib

export PATH=$PATH:/usr/local/protobuf/bin

##### 内容结束 #####

> source /etc/profile

> protoc --version

12345678910111213141516171819

> sudo apt-get install autoconf automake libtool curl make g++ libffi-dev -y

> cd /usr/local/src/

> wget https://github.com/protocolbuffers/protobuf/releases/download/v3.12.0/protobuf-all-3.12.0.tar.gz

> tar zxvf protobuf-all-3.12.0.tar.gz

> cd protobuf-3.12.0/

> ./autogen.sh

> ./configure --prefix=/usr/local/protobuf

> make

> make check

> make install

> ldconfig

> vim /etc/profile

##### 增加如下内容 #####

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/protobuf/lib

export LIBRARY_PATH=$LIBRARY_PATH:/usr/local/protobuf/lib

export PATH=$PATH:/usr/local/protobuf/bin

##### 内容结束 #####

> source /etc/profile

> protoc --version

使用

语法

syntax = "proto3";

message 消息名 {

消息体

}

示例

response.proto

// 指定protobuf的版本,proto3是最新的语法版本

syntax = "proto3";

// 定义数据结构,message 你可以想象成java的class,c语言中的struct

message Response {

string data = 1; // 定义一个string类型的字段,字段名字为data, 序号为1

int32 status = 2; // 定义一个int32类型的字段,字段名字为status, 序号为2

}

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

分配标识号

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

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

[1,15]之内的标识号在编码的时候会占用一个字节。

[16,2047]之内的标识号则占用2个字节。

所以应该为那些频繁出现的消息元素保留 [1,15]之内的标识号。

切记:要为将来有可能添加的、频繁出现的字段预留一些标识号。

保留标识号

message Foo {

reserved 2, 15, 9 to 11; // 保留2,15,9到11这些标识号

}

注释

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

为消息定义包

package foo.bar;

message Open { ... }

选项

java_package 单独为java定义包名字。

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

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

1234

##### 命令格式:

> protoc [OPTION] PROTO_FILES

##### 例子:

> protoc --java_out=. demo.proto

常用的OPTION选项:

--cpp_out=OUT_DIR 指定代码生成目录,生成 C++ 代码

--csharp_out=OUT_DIR 指定代码生成目录,生成 C# 代码

--java_out=OUT_DIR 指定代码生成目录,生成 java 代码

--js_out=OUT_DIR 指定代码生成目录,生成 javascript 代码

--objc_out=OUT_DIR 指定代码生成目录,生成 Objective C 代码

--php_out=OUT_DIR 指定代码生成目录,生成 php 代码

--python_out=OUT_DIR 指定代码生成目录,生成 python 代码

--ruby_out=OUT_DIR 指定代码生成目录,生成 ruby 代码

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

maven:

12345

com.google.protobuf

protobuf-java

3.9.1

1234567891011121314151617

ResponseOuterClass.Response.Builder builder = ResponseOuterClass.Response.newBuilder();

// 设置字段值builder.setData("hello www.wanglibing.com");

builder.setStatus(200);

ResponseOuterClass.Response response = builder.build();

// 将数据根据protobuf格式,转化为字节数组 byte[] byteArray = response.toByteArray();

// 反序列化,二进制数据try {

ResponseOuterClass.Response newResponse = ResponseOuterClass.Response.parseFrom(byteArray);

System.out.println(newResponse.getData());

System.out.println(newResponse.getStatus());

} catch (Exception e) {

}

Golang使用protobuf

12345678910

##### 1. 安装protobuf编译器(步骤略)

##### 2. 安装protobuf包

> go get -v -u github.com/golang/protobuf/proto

##### 3. 安装protoc-gen-go插件

> go get -v -u github.com/golang/protobuf/protoc-gen-go

##### 4. 定义proto消息(步骤略)

##### 5. 不带插件编译

> protoc --go_out=./ *.proto

##### 5. 带插件编译

> protoc --go_out=plugins=grpc:./ *.proto

基本数据类型

double

float

int32 使用变长编码,对于负值的效率很低,如果你的域有可能有负值,请使用sint64替代

uint32 使用变长编码。

uint64 使用变长编码。

sint32 使用变长编码,这些编码在负值时比int32高效的多。

sint64 使用变长编码,有符号的整型值。编码时比通常的int64高效。

fixed32 总是4个字节,如果数值总是比总是比228大的话,这个类型会比uint32高效。

fixed64总是8个字节,如果数值总是比总是比256大的话,这个类型会比uint64高效。

sfixed32 总是4个字节。

sfixed64 总是8个字节。

bool

string 一个字符串必须是UTF-8编码或者7-bit ASCII编码的文本。

bytes 可能包含任意顺序的字节数据。

枚举类型

syntax = "proto3";//指定版本信息,不指定会报错

enum PhoneType //枚举消息类型,使用enum关键词定义,一个电话类型的枚举类型

{

MOBILE = 0; //proto3版本中,首成员必须为0,成员不应有相同的值

HOME = 1;

WORK = 2;

}

// 定义一个电话消息

message PhoneNumber

{

string number = 1; // 电话号码字段

PhoneType type = 2; // 电话类型字段,电话类型使用PhoneType枚举类型

}

数组类型

整数数组

message Msg {

// 只要使用repeated标记类型定义,就表示数组类型。

repeated int32 arrays = 1;

}

字符串数组

message Msg {

repeated string names = 1;

}

消息嵌套

引用其它消息类型

// 定义Result消息

message Result {

string url = 1;

string title = 2;

repeated string snippets = 3; // 字符串数组类型

}

// 定义SearchResponse消息

message SearchResponse {

// 引用上面定义的Result消息类型,作为results字段的类型

repeated Result results = 1; // repeated关键词标记,说明results字段是一个数组

}

消息嵌套

message SearchResponse {

// 嵌套消息定义

message Result {

string url = 1;

string title = 2;

repeated string snippets = 3;

}

// 引用嵌套的消息定义

repeated Result results = 1;

}

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

result.proto

syntax = "proto3";

// Result消息定义

message Result {

string url = 1;

string title = 2;

repeated string snippets = 3; // 字符串数组类型

}

search_response.proto

syntax = "proto3";

// 导入Result消息定义

import "result.proto";

// 定义SearchResponse消息

message SearchResponse {

// 使用导入的Result消息

repeated Result results = 1;

}

map类型

map语法

map map_field = N;

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

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

map示例

syntax = "proto3";

message Product

{

string name = 1; // 商品名

// 定义一个k/v类型,key是string类型,value也是string类型

map attrs = 2; // 商品属性,键值对

}

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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值