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.x与ProtoBuf3.x使用差别:
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
做个笔记