码迷,mamicode.com
首页 > 其他好文 > 详细

Google protocol buffers 小结(二)

时间:2016-04-29 18:42:33      阅读:200      评论:0      收藏:0      [点我收藏+]

标签:

protobuf是什么

protobuf,全称Google protocol bufferGoogle公司内部的混合语言数据标准,用于RPC系统和持续数据存储系统

它是一种轻便高效的结构化数据存储格式,可以用于结构化数据串行化,或者说序列化,适合做数据存储或RPC数据交换格式,可用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。目前提供了 C++JavaPython三种语言的 API

为什么要使用protobuf

提到protobuf,一般会与XML做比较,protobuf优点:

XML相比,protobuf更小,更快,更简单,可以自定义数据结构,用代码生成器来生成可读代码;另外protobuf支持向后兼容,不必破坏老的数据格式的程序,即可进行升级,不必担心消息结构改变而造成的大规模代码重构或迁移问题;protobuf语义更清晰,无需类似XML解析器的东西,protobuf编译器会将.proto文件编译生成对应的数据访问类以对protobuf数据进行序列化、反序列化操作;protobuf无需学习复杂的文档对象模型,protobuf简单易学,拥有良好的文档和示例,能快速上手。

Protobuf缺点:

XML相比protobuf要成熟,已经成为行业标准,protobuf只是Google内部使用的工具,通用性比较差

Protobuf序列化后生成的是二进制消息,除非有.proto定义,没法直接读出protobuf的内容,而XML具有某种程度上的自解释性,可被人直接读取编辑;protobuf不适用基于文本的标记文档(HTML)建模

怎么使用protobuf

Protobuf简单例子

      

技术分享

 

1

         组成部分:message关键字,类似java中的class关键字;HellowWorld消息名,类似java中的类名;required/optional/repeated是限定符,required表示序列化或反序列化之前,该字段不能为空,一个message中至少要有一个required限定字段optionalrepeated没有该限制,其中optional表示选填,可以设置默认值,一个message中允许0个或多个optional限定字段(参考图2),如果未设置,在序列化是如果该字段内容为空,则根据类型,如果类型为int32/int64则默认为0,如果类型为string则默认为空串,如果类型为boolean则默认为falserepeated多用来表示数组,repeated定义的字段允许0个或多个数据int32/int64/string等类型为protobuf中的基本数据类型

技术分享

 

2

Protobuf支持消息嵌套,支持枚举,支持一个message作为另一个message的字段属性,如图3

技术分享

 

3

如何实现不同的.proto文件中,message公用呢?可以如java一般,引入import关键字,例如A.proto文件在pro路径下,且存在一个名为commonmessageB.proto文件想引用common,则需要在文件的packageprotobuf的包名,序列化后生成对应java文件的包名,c++文件的namespace)下,message之前引用:import “pro/A.proto”

Protobuf的基本数据类型与javac++对照表如图4

技术分享

 

4

Protobufoptions

Protocol Buffer允许我们在.proto文件中定义一些常用的选项,这样可以指示Protocol Buffer编译器帮助我们生成更为匹配的目标语言代码。Protocol Buffer内置的选项被分为以下三个级别:
1. 文件级别,这样的选项将影响当前文件中定义的所有消息和枚举。

2. 消息级别,这样的选项仅影响某个消息及其包含的所有字段。

3. 字段级别,这样的选项仅仅响应与其相关的字段。

文件级别的选项有:

     java_package通过指定该选项可以让生成Java代码的包名为该选项值,例如[optionjava_package=”com.hik.web.proto”],则生成java文件的包是在com.hik.web.proto下,如果没有指定该选项,Java的包名则为package关键字指定的名称,此选项仅对生成java代码有效

    java_outer_classname该选项指定生成的Java类名,例如:[optionjava_outer_classname=”Hpp”],如果没有指定该选项,Java文件名为proto文件的名称,并且会将名称转换为驼峰模式,比如.proto文件名为my_proto.proto,则生成的java文件名为MyProto.java,此选项仅对java代码生效

    optimize_for—Protocol Buffer定义三种优化级别SPEED/CODE_SIZE/LITE_RUNTIME。缺省情况下是SPEEDSPEED表示生成的代码运行效率高,但生成的代码编译后会占用更多的空间;CODE_SIZESPEED相反,生成的代码运行效率会低,但生成的代码编译后占用空间更小,适用于资源有限的平台,比如mobileLITE_RUNTIME生成代码的执行效率高,并且生成编译后占用的空间也比较小,这是通过牺牲protobuf提供的反射功能实现的,使用该选项,Javac++需要protobuf-lite相关包或连接

字段级别的选项有:

     packed=true--对于数值型的repeated字段,如int32int64等,在编码时并没有得到很好的优化,然而在新近版本的Protocol Buffer中,可通过添加[packed=true]的字段选项,以通知Protocol Buffer在为该类型的消息对象编码时更加高效(该optionprotobuf2.3.0以上版本才生效)

    default=default_value这个主要用于optional字段设置默认值,上面有介绍

protobuf命令行

        

技术分享

 

5

protoc--命令行编译工具

--proto_path等同于-I,指定要编译的proto文件目录,该选项可以指定多个

--java_out编译成Java文件,并指定生成java文件的目录,同样的还有cpp_out生成c++文件,python_out生成python文件

path/file.proto表示待编译的proto文件

可以编写一个protoc.bat文件内容如图6

Google protocol buffers 小结(二)

标签:

原文地址:http://blog.csdn.net/xdq_0518/article/details/51241036

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!