您好,欢迎访问三七文档
当前位置:首页 > 行业资料 > 交通运输 > protobuf概述
1.概述ProtocolBuffers是一种轻便高效的结构化数据存储格式,可以用于结构化数据串行化,或者说序列化。它很适合做数据存储或RPC数据交换格式。可用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。目前提供了C++、Java、Python三种语言的API。本文概述介绍ProtocolBuffers,以及开始如何开始ProtocolBuffers之旅,本系列主要以Java为主(虽然超想看Python的,无奈学的还不够…)。以下ProtocolBuffers简称PB。2.ProtocolBuffers是什么ProtocolBuffers提供了一种灵活,高效,自动序列化结构数据的机制,可以联想XML,但是比XML更小,更快,更简单。仅需要自定义一次你所需的数据格式,然后用户就可以使用ProtocolBuffers自动生成的特定的源码,方便的读写用户自定义的格式化的数据。不限语言,不限平台。还可以在不破坏原数据格式的基础上,依据老的数据格式,更新现有的数据格式。3.ProtocolBuffers如何工作的在PB中,有一种.proto类型的文件,用户在.proto文件中定义PB“Message”来指定所需要序列化的数据的格式。每一个PBMessage都是一个小的信息逻辑单元,包含了一些列的name-value对。下面举例说明一个简单地.proto文件,他定义了一条包含一个Person信息的Message:messagePerson{requiredstringname=1;requiredint32id=2;optionalstringemail=3;enumPhoneType{MOBILE=0;HOME=1;WORK=2;}messagePhoneNumber{requiredstringnumber=1;optionalPhoneTypetype=2[default=HOME];}repeatedPhoneNumberphone=4;}如上代码所示,PBmessage格式非常简单。每种类型的message包含一个或者多个唯一编码字段,每个字段由名称和值类型组成,值类型可以使数字(整形或者浮点型),布尔值,字符串,原始字节,甚至是其他的PBmessage。PB允许message中包含message,已达到分层嵌套。可以定义可选字段,必填字段以及重复字段。想要了解更多如何写.proto文件,可以访问:ProtocolBufferLanguageGuide定义好PBmessage后,选择合适语言的PB编译器,编译.proto文件,就可以生成存取数据的相关类。这些类包括简单的设置及读取字段的方法,也包括对整个数据结构的message与二进制之间的转换。举个例子,如果你使用的语言是java,运行编译器编译上例.proto文件后,生成的类中包含一个Person类。使用该类,就可以计算,序列化以及检索PBmessage。如下代码:publicstaticvoidmain(String[]args)throwsIOException{Personjohn=Person.newBuilder().setId(1).setName(john).setEmail(john@youku.com).addPhone(PhoneNumber.newBuilder().setNumber(1861xxxxxxx).setType(PhoneType.WORK).build()).build();FileOutputStreamoutput=newFileOutputStream(abc.txt);john.writeTo(output);output.close();}接下来,你可以用如下代码读取:publicstaticvoidmain(String[]args)throwsIOException{FileInputStreaminput=newFileInputStream(abc.txt);Personperson=Person.parseFrom(input);System.out.println(person.getId());System.out.println(person.getName());System.out.println(person.getEmail());System.out.println(person.getPhoneCount());System.out.println(person.getPhone(0).getNumber());System.out.println(person.getPhone(0).getType());}PB是易于扩展的,可以向后兼容的,我们可以在PBmessage中添加新的字段,这样,在parse的时候,老版本的数据就会简单的忽略新增加的字段。因此,如果现有通信协议使用了PB作为其数据格式,我们可以直接扩展该通信协议,而不必担心这将会破坏现有的代码。对于使用.proto文件生成PB客户端代码,可以参看这方面的完整教程:APIReferencesection。想要学习了解PBmessage是如何编码的,可以参见:ProtocolBufferEncoding。4.为什么不直接使用XML呢?如果要序列化结构化数据,比起XML,PB实在是有许多的优点可以道道~1.更简单2.比XML小3~10倍3.比XML快20~100倍4.语义定义明确5.自动生成数据存取类,更容易使用假如我们要模拟一个Person,该对象包含name和email属性,如果用XML,我们定义如下:personnameJohnDoe/nameemailjdoe@example.com/email/person对应的,PB如下:person{name:JohnDoeemail:jdoe@example.com}请注意:这里仅是PB格式的一种直观表示,真实的PB并非这样存储,实际上,在链路中,PB数据时二进制格式的。当这段数据编码为PB二进制格式时,其实际大小大概是28bytes,编码时间为100~200纳秒。如果用XML的话,即使去除空格,大小也至少为69bytes,编码时间大概需要5000~10,000纳秒。同样,解析这段代码,PB比XML要方便许多。用PB的话:person.getName();person.getEmail();而用XML的话:personNode.getElementsByTagName(name)personNode.getElementsByTagName(email)相比起来,PB更直接,而且不需要遍历节点等XML操作。但是,金无足赤,人无完人,PB也一样。对于有很多标签的,基于文本的数据(例如HTML),XML就完胜PB。XML是子描述的,可以随机且交错读取读取文本节点。XML是自描述的,而PB不是,PB必须要有格式定义文件(.proto文件)5.一点历史PB由Google开发,最初是用于处理索引服务器的请求/响应协议。在有PB之前,Google使用手动编组和解组的方式来处理请求/相应协议。这种方式需要支持许多版本的协议,这就导致一些代码非常的丑陋,例如:if(version==3){...}elseif(version4){if(version==5){...}...}另外,这种显示格式的协议同样将新发布的协议版本也搞得非常复杂,因为开发者必须在启用新的协议之前,确认所有的服务器,包括请求的发起者以及实际处理请求者,他们都能够理解新的协议。PB即被设计来解决这些问题:1.要可以非常容易的引入新字段,不需要检查数据的中间服务器能够简单地解析数据,并且无须知道数据所有的字段就可以传输数据。2.格式能够更加的自描述一些,并且可以被多用语言处理(C++,Java,Python等)至此,虽然解决了诸多问题,但用户依然需要手写他们的解析及编码代码。随着系统的发展,PB逐渐形成了许多新的特性及用法:1.自动生成序列化及反序列化代码,避免手动解析2.除了被用在短生命周期的RPC请求,也开始将PB作为一种方便的自描述格式去存储持久化数据。3.ServerRPCinterfaces开始被声明为协议文件的一部分,使用PBcompiler生成stub类,用户可以使用自己实现的服务器接口来覆盖他们。GoogleProtocolBuffer(简称Protobuf)是Google公司内部的混合语言数据标准,目前已经正在使用的有超过48,162种报文格式定义和超过12,183个.proto文件。他们用于RPC系统和持续数据存储系统。
本文标题:protobuf概述
链接地址:https://www.777doc.com/doc-2852945 .html