JavaProtobuf的概括介绍、使用和分析

1、创建product.proto文件

        定义了多少个Message(ProductInfo、PhoneInfo、Watch)音信结构

Java 1

b、demo生成的的二进制文件反系列化。

第1个字节 (0A)

字段索引(index):         0A = 0001010  0A>>3 = 001 = 1

数据类型(type):           0A = 0001010&111  = 2 (String);

 

第2个字节 (0C)

字符串长度(length):      0E = 12;

字符串:                         0A 05 69 64 6F 6C 33 10 01 18 BD 0F

 

第3个字节 (0A)

因为字符串是出自phoneInfo属于嵌套类型

字段索引(index):         0A = 0001010  0A>>3 = 001 = 1

数据类型(type):           0A = 0001010&111  = 2 (String);

第4-9个字节(69 64 6F 6C 33)

字符串长度(length):    05 = 5

字符串:                       69 64 6F 6C 33 = idol3

 

第10个字节 (10)

字段索引(index):         10 = 00010000    10A>>3 = 0010 = 2

数据类型(type):           10 = 00010000&111  = 0 (Varints);

 

第11个字节  (01)

Varints:                          01 = 00001字节的万丈位为0 整数截止

Value:                            1;

 

第12个字节(18)

字段索引(index):           18 = 00011000    18>> 00011 = 3

数据类型(type):           18 = 00011000&111  = 0 (Varints);

 

第13个字节(D0)

最高位为1,整数总结到下一个字节

 

第14个字节(0F)

摩天位为0,整数总计甘休

Value:为11111010000 =2000

 

二、protobuf有什么?

        Protobuf
提供了C++、java、python语言的支撑,提供了windows(proto.exe)和linux平台动态编译生成proto文件对应的源文件。proto文件定义了切磋数据中的实体结构(message
,field)

关键字message: 代表了实体结构,由三个信息字段(field)组成。

新闻字段(field): 包涵数据类型、字段名、字段规则、字段唯一标识、默许值

数据类型:常见的原子类型都支持(在FieldDescriptor::kTypeToName中有定义)

字段规则:(在FieldDescriptor::kLabelToName中定义)

        required:必须开头化字段,假若没有赋值,在数额系列化时会抛出很是

        optional:可选字段,可以无需开端化。

        repeated:数据足以重新(相当于java 中的Array或List)

        字段唯一标识:系列化和反序列化将会利用到。

默认值:在概念音信字段时可以给出默认值。

 

七、Protobuf的源码分析

2、音信结构对应的java类(ProductInfo、PhoneInfo、沃特ch)

Java 2

 

4、空间功能

xml、json是用字段名称来规定类实例中字段之间的独立性,所以体系化后的数量多了无数描述音讯,伸张了连串化后的字节连串的容量。

 

Protobuf的体系化/反连串化进度可以汲取:

protobuf是由字段索引(fieldIndex)与数据类型(type)总计(fieldIndex<<3|type)得出的key维护字段之间的炫耀且只占一个字节,所以比较json与xml文件,protobuf的连串化字节没有过多的key与讲述符新闻,所以占用空间要小很多。

4、JSON字符串

 

{“phone”:{“phoneName”:”idol3″,”price”:2000,”top”:1},”watch”:{“watchName”:”tcl
wtch”,”top”:1,”price”:1000}}

 

a、规则:

protobuf把新闻结果message也是由此key-value对来代表。只是其中的key是行使一定的算法计算出来的即经过各种message中每个字段(field
index)和字段的数据类型举办演算得来的key = (index<<3)|type;

type类型的照应关系如下:

 

Type

Meaning

Used For

0

Varint

int32, int64, uint32, uint64, sint32, sint64, bool, enum

1

64-bit

fixed64, sfixed64, double

2

Length-delimited

string, bytes, embedded messages, packed repeated fields

3

Start group

groups (deprecated)

4

End group

groups (deprecated)

5

32-bit

fixed32, sfixed32, float

 

Value会根据数据类型的不一样会有二种表现方式:

对于各类int,bool,enum类型,value就是Varint

对此string,bytes,message等等类型,value就是length+原始内容编码

 

Varints是一种紧凑表示数字的点子。它用一个依旧多个字节表示一个数字,值越小的数字字节数越少。相对于传统的用4字节意味着int32品种数字,Varints对于小于128的数值都得以用一个字节表示,大于128的数值会用越多的字节来表示,对于很大的数码则需求用5个字节来代表。

 

Varints算法描述:
每一个字节的最高位都是有分外含义的,要是是1,则代表继续的字节也是该数字的一片段;若是是0,则甘休

C、反连串化结果

phoneinfo为

phoneName = “idol3”

top = 1

price = 2000;

 

无异于的格局watchInfo为:

watchName = “tcl name”

top = 1

price=2000 

5、Protobuf转化后的二进制文件

Java 3

 

空中功用

Json:107个字节

Protobuf:32个字节

 

时刻功能

Json序列化: 1ms ,  反序列化:0ms

Protobuf 序列化: 0ms 反种类化:0ms

 

将public List<Phone> list和repeated PhoneInfo phoneInfoList
=3;都赋值为1000个PhoneInfo

 

空间成效

Json:4206个字节

Protobuf:1332个字节

 

时光效能

Json序列化: 4ms ,  反体系化:1ms

Protobuf 序列化: 1ms 反种类化:0ms

2、java使用protobuf 的反连串化流程分析

java程序通过调用parserFrom(byte[] data)起始反系列化

 Java 4

Java 5

切实在com.google.protobuf. AbstractParser类中已毕

 

Java 6

 

Java 7

Java 8

 

Java 9

 

 

终极在com.google.protobuf.CodedInputStream类中做到反体系化

3、时间功用

通过protobuf体系化/反连串化的进度能够汲取:protobuf是经过算法生成二进制流,种类化与反系列化不需求分析相应的节点属性和多余的叙述音信,所以种类化和反种类化时间功用较高。

3、消息结构和java对象赋值

PhoneName:” idol3”

Price:2000

Top:1

 

WatchName:” tcl watch”

Price:1000

Top:1

 

1、protobuf在java使用的体系化流程

 

java程序调用parserFrom(byte[]
data)开始字节体系的反种类,Java程序通过调用编译生类GenerateMessage中的wirteTo()方法起首将连串化后的字节写入输出流中

 Java 10

Java 11

GenerateMessage
继承AbstractMessage类,连串化最后在AbstractMesssage中做到,种类化的落到实处过程:

a、遍历对象中Message结构()

调用AbstractMessage类中的writeTo()方法

 Java 12

b、 种类化Message中每一个字段

调用CodeOutputStream类中的writeMessageSetExtension()方法

Java 13

 

c、 对于Varints  Tag 的连串化流程:

调用CodeOutputStream类中的writeUInt32()方法

Java 14

调用CodeOutputStream类中的WriteRawVarint32()方法

Java 15

 

d、 对于非Varints Tag的体系化

调用CodeOutputStream类中的WriteTag()方法

Java 16 

Java 17

 

实际的系列化达成都在CodedOutputStream中形成

 

四、Protobuf在Android上的施用

1、创立proto文件,定义新闻的实体结构

2、编译proto文件生成对应的java文件

3、添加protobuf-java-2.5.0.jar到android工程

4、在android中贯彻对音信结构的种类化/反系列化  

 

五、Protobuf与json的对比

3、动态编译

以windows下用protoc.exe工具完结proto文件编译为例,protoc.exe是用C++达成。在控制台执行命令:

Java 18

编译的流程:

反省proto的语法规则

将proto的公文中的message结构转换为GenerateMessage类的子类,并已毕Builder接口。

编译流程

Main.cc中的main()方法

Java 19

 

Command_line_interface.cc中的Run()方法

Java 20

 

Import类中Import()

Java 21

 

在Descriptor中做到message新闻的采集和中转。

六、protobuf的大约分析

1、优缺点

亮点:通过上述的光阴作用和空中功效,可以看出protobuf的长空功效是JSON的2-5倍,时间功能要高,对于数据大小敏感,传输功能高的模块可以行使protobuf库

 

缺陷:音信结构可读性不高,体系化后的字节体系为二进制系列无法简单的剖析有效性;近来应用不广泛,只帮衬java,C++和Python;

 

2、数据种类化/反体系化

 

 

一、protobuf是什么?

        protobuf(谷歌 Protocol
Buffers)是谷歌提供一个持有快捷的磋商数据交流格式工具库(类似Json),但相比较于Json,Protobuf有更高的转发功用,时间功能和空中功效都是JSON的3-5倍。前边将会有大致的demo对于那二种格式的数目转载功效的自查自纠。但这一个库如今应用还不是太流行,据说谷歌(Google)之中很多产品都有使用。

 

三、protobuf有怎么样用?

       
Xml、Json是时下常用的数据互换格式,它们一贯运用字段名称爱惜连串化后类实例中字段与数码里面的照耀关系,一般用字符串的款式保留在系列化后的字节流中。新闻和音信的定义相对独立,可读性较好。但序列化后的数额字节很大,体系化和反系列化的光阴较长,数据传输功用不高。

       
Protobuf和Xml、Json种类化的格局各异,选取了二进制字节的系列化方式,用字段索引和字段类型通过算法统计得到字段从前的涉嫌映射,从而落成更高的时日效用和空中功效,越发符合对数码大小和传输速率相比灵活的场馆使用。

Protobuf的不难介绍、使用和剖析

 

相关文章