google protocol buffer基础学习总结(java版)

来源:互联网 发布:mac 命令行下载文件 编辑:程序博客网 时间:2024/06/07 01:54

1.什么是Protocol Buffer

简单来说protobuf是一种与语言和平台无关的数据传输的格式。

ps.protobuf时google开发的,从google官方github上了解到目前提供了对C++,C#,JAVA,OC,JS,Ruby,PHP,Python和Go语言的支持。


2.Protocol Buffer的优缺点?

优点:

        *相对于JSON,XML之类的数据交换格式来说,二进制格式的protocol buffer数据量小,性能和效率高。

       ps.笔者自己学习过程中一条协议使用json传输大概是8800多字节,而是用protocol buffer只有3300多字节将json转换为100000次平均时长0.08毫秒,将二进制的protocol buffer数据转换为对象100000次平均时间为0.02毫秒,虽然只是在毫秒级,但是这只是小数据量的测试,数据量越大差距就越明显。

 *代码生成。实际在项目中我们使用到的协议类是通过protocol buffer进行生成的。

缺点:

  *二进制格式的数据可读性差。


3.如何使用Protocol Buffer?

上面在介绍protocol buffer的优点中提到了代码生成,实际项目中应用protocol buffer,协议部分的类一般都是通过生成代码得到。


         那么如何生成协议部分的类代码呢?这里就需要提到.proto文件及如何定义.proto文件。

         首先我会先贴上一个例子:该例子也是网上很多其他讲解protobuf文章中使用到的例子

              

               参照上述示例,先说明其中的主要的关键字的含义:

               message:用来定义一个消息体。它对应会生成一个类。

               required:用于限定消息中的一个字段是必须要进行主动赋值的。如你发送请求前必须对该字段主动设置一个值,否则会抛出一个未初始化的异常。

               optional:同required也是用来限定消息体中的字段,但是顾名思义:可选的。不必对该字段进行主动赋值。

               repeated:意思是可重复性的。用于限定一个字段是可以拥有很多元素,对应于java中的list集合。

               (ps: required,optional,repeated三个限定符,每个字段只能三选一)

               Tag:Tag他不是一个关键词。上述例子中可以看到每个message中的每个字段的等号中都会有一个数字,这里需要声明他不是字段的值或者默认值,而是我所说的Tag。它是字段的标识符,用于标记字段,同一个message中的Tag不允许重复,而且不能为负数。Tag值得范围1~229 - 1,其中19000至19999为保留值不能使用。

                default:用于为字段指定默认的值。注意即便是限定为required的字段设置了default默认值,在实际使用中还是需要进行主动赋值。

                 enum:用于在.proto中定义一个枚举类型。其值必须为32位整型的非负数值。注意enum中元素等号后的数值不是上面说的Tag而是元素的字面值。


                  对于java_outer_classname和java_package需要特别说明的几点:

                   1.一个.proto文件只会生成一个.java文件。

     2.java_outer_classname用于声明生成的.java文件中的外部内类名,.proto文件中定义的message将会生成为其内部类。

  3.java_package用于指定生成的java_outer_classname类的包名。


                  数据类型的参照表:

                   

(ps:repeated确切来说不是类型,笔者将其加在类型表,只是为了声明repeated的字段将生成类型为List类型的字段)

4.ProtoBuf2.xProtoBuf3.x使用差别:

•2.X中字段的限定必须为required、optinal或repeated之一;3.x不再支持required、optional限定符。
•3.x中不支持指定默认值,即default不允许使用。
•3.x中的枚举类型的元素值必须从0开始
•3.x的编译器要求必须在.proto文件内容的首行使用syntax指定版本。(syntax = “proto2”或syntax = “proto3”)
(ps:都他妈一个个试出来的)
5.如何生成代码?
这里我只写生成代码的命令行的格式。
•protoc --proto_path=IMPORT_PATH --java_out=DST_DIR .proto_file_path

Ps:--proto_path可以简写成:-I

1.--proto_path=IMPORT_PATH:IMPORT_PATH用于指定编译时.proto的导入路径。可以指定多个--proto_path

2.--java_out=DST_DIR:DST_DIR指定编译工具生成的代码存放路径。

3 .proto_file_path:指定需要编译的.proto文件的绝对路径。可以指定多个。Ps:文件必须在proto_path目录下

        

ps:通过上述的例子group.proto文件定义来解释--proto_path=IMPORT_PATH

比如我的test.proto文件路径c:/code/bin/test.proto

group.proto文件路径c:/code/group.proto

test.proto文件中定义了一个message为Person

而group.proto文件中的GroupManager的message中要使用test.proto中的person

引用不同文件的message,就需要使用上述的import语句进行导入

而其中的import后面跟的是导入路径,此路径只能为相对路径,相对于--proto_path=IMPORT_PATH的路径

上述中的import后的相对路径为"bin/test.proto",那么IMPORT_PATH就为c:/code



做个笔记

原创粉丝点击