一、介绍

Google提供一个具有高效的协议数据交换格式工具库(类似Json),但相比于Json,Protobuf有更高的转化效率,时间效率和空间效率都是JSON的3-5倍。google 提供了三种语言的实现:java、c++ 和 python,每一种实现都包含了相应语言的编译器以及库文件。

二、特点

Xml、Json是目前常用的数据交换格式,它们直接使用字段名称维护序列化后类实例中字段与数据之间的映射关系,一般用字符串的形式保存在序列化后的字节流中。消息和消息的定义相对独立,可读性较好。但序列化后的数据字节很大,序列化和反序列化的时间较长,数据传输效率不高。

Protobuf和Xml、Json序列化的方式不同,采用了二进制字节的序列化方式,用字段索引和字段类型通过算法计算得到字段之前的关系映射,从而达到更高的时间效率和空间效率,特别适合对数据大小和传输速率比较敏感的场合使用。

三、结构

proto文件定义了协议数据中的实体结构(message ,field)。

举例如下:

  1. //要生成的类Person
  2. message Person {
  3. required string name = 1;
  4. required int32 id = 2;
  5. optional string email = 3;
  6. enum PhoneType {
  7. MOBILE = 0;
  8. HOME = 1;
  9. WORK = 2;
  10. }
  11. message PhoneNumber {
  12. required string number = 1;
  13. optional PhoneType type = 2 [default = HOME];
  14. }
  15. repeated PhoneNumber phone = 4;
  16. }

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

Message中定义的全部属性在class中全部为private的。

Message的嵌套使用可以嵌套定义,也可以采用先定义再使用的方式。

(2)消息字段field: 即属性,包括字段规则+数据类型+字段名+属性顺序号+[默认值]。

  • 数据类型:常见的原子类型都支持

  • 字段规则:

    • required:对于required的字段而言,必须初始化字段,否则会抛异常
    • optional:可选字段,可以不必初始化。如果没初始化,那么将赋予该字段编号一个默认值。int或者char数据类型默认为0,string默认为"",bool默认为false,嵌套message默认为构造,枚举则为第一个。
    • repeated:数据可以重复(相当于java 中的Array或List)
  • 字段唯一标识:序列化和反序列化将会使用到。比如上面的=1; =2;

  • 默认值:在定义消息字段时可以给出默认值。比如 [default = HOME]

四、选择版本

syntax 声明可以选择protobuf的编译器版本(v2和v3)

  • syntax="proto2":选择2版本,各个字段必须明确标注编号以确定序列化后二进制数据字段的位置
  • syntax="proto3":选择3版本,没有强制使用字段编号,proto3 已舍弃 required 字段,optional 字段也无法显示使用

五、Intellij IDEA中使用Protobuf

1、下载个protoc.exe

2、编辑个.proto文件

在proto文件下创建一个AddressBook.proto。用的是proto2版本

里面的结构就是 AddressBook下有很多个Person。

每个Person必须有一个name、必须有一个id、可选有email、很多个PhoneNumber。

每个PhoneNumber必须有一个number、可选PhoneType。

PhoneType取值必为0或1或2

写的内容举例如下:

  1. syntax = "proto2";
  2. //生成的类会放在protoc.exe同目录下的tutorial
  3. //如果.proto文件中写了java_package,就以java_package为准。
  4. package beans;
  5. //生成的类会放在protoc.exe同目录下的com.proto.tutorial下
  6. //option java_package = "com.proto.tutorial";
  7. //最终成的类名
  8. //option java_outer_classname = "AddressBookProtos";
  9. message Person {
  10. required string name = 1;
  11. required int32 id = 2; .
  12. optional string email = 3;
  13. enum PhoneType {
  14. MOBILE = 0;
  15. HOME = 1;
  16. WORK = 2;
  17. }
  18. message PhoneNumber {
  19. required string number = 1;
  20. optional PhoneType type = 2 [default = HOME];
  21. }
  22. repeated PhoneNumber phone = 4;
  23. }
  24. message AddressBook {
  25. repeated Person person = 1;
  26. package tutorial;
  27. option java_package = "com.proto.tutorial";
  28. option java_outer_classname = "AddressBookProtos";
  29. message Person {
  30. required string name = 1;
  31. required int32 id = 2; // Unique ID number for this person.
  32. optional string email = 3;
  33. enum PhoneType {
  34. MOBILE = 0;
  35. HOME = 1;
  36. WORK = 2;
  37. }
  38. message PhoneNumber {
  39. required string number = 1;
  40. optional PhoneType type = 2 [default = HOME];
  41. }
  42. repeated PhoneNumber phone = 4;
  43. }
  44. message AddressBook {
  45. repeated Person person = 1;
  46. }

3、将.proto文件转成Java类

控制台中执行protoc命令,依次将.proto文件转成Java类

  1. protoc.exe -I=F:/workspace/proto-test/src/main/resources/proto --java_out=F:/workspace/proto-test/src/main/java/beans F:/workspace/proto-test/src/main/res
  2. ources/proto/AddressBook.proto
  3. protoc.exe -I=(proto文件所在绝对路径,不包括proto文件本身)  --java_out=(文件输出目录) (proto文件所在绝对路径,包括proto文件名)

4、相关包

  1. <dependency>
  2. <groupId>com.google.protobuf</groupId>
  3. <artifactId>protobuf-java</artifactId>
  4. <version>3.7.1</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>com.googlecode.protobuf-java-format</groupId>
  8. <artifactId>protobuf-java-format</artifactId>
  9. <version>1.2</version>
  10. </dependency>

5、.proto文件语法高亮显示

需要安装Protobuf Support插件,

依次点击Intellij中的“File”-->"Settings"-->"Plugins"-->"Browse repositories",

输入Protobuf,点击install

6、具体使用举例

  1. AddressBookProtos.AddressBook .Builder addressBook= AddressBookProtos.AddressBook .newBuilder();
  2. AddressBookProtos.Person .Builder person= AddressBookProtos.Person .newBuilder();
  3. person.setName("Mike");
  4. addressBook.setPerson(person);

IDEA下使用protobuf2(java)的更多相关文章

  1. gen目录无法更新,或者gen目录下的R.JAVA文件无法生成

    gen目录无法更新,或者gen目录下的R.JAVA文件无法生成 1.gen目录的用处 android gen目录下的R.java并不是由用户创建,而是android工程本身将android的资源进行自 ...

  2. Ubuntu下安装了java但启动eclipse报错说没装java

    参考资料:http://blog.csdn.net/happyteafriends/article/details/8290950 一.问题 在Ubuntu下安装了java并在~/.bashrc配置了 ...

  3. 不错的linux下通用的java程序启动脚本

    不错的linux下通用的java程序启动脚本(转载) 虽然写起动shell的频率非常不高...但是每次要写都要对付一大堆的jar文件路径,新加jar包也必须要修改起动shell. 在网上找到一个挺好的 ...

  4. DOS命令下输入:java Hello 出现以下几种结果可能的原因:

    DOS命令下输入:java Hello 出现以下结果:Bad command or the file name 没有这个命令或文件名 原因可能是没有成功安装jdk或者没有配置好jdk 的环境变量,或者 ...

  5. 使用 NIO.2 遍历目录下所有的Java文件

    package wellGrounded; import java.io.IOException; import java.nio.file.FileVisitResult; import java. ...

  6. Ubuntu 下安装 Oracle Java

    这只是一篇流水帐,记录如何安装Java. 在Ubuntu 下管理软件很方便,但安装的Java是opensdk.如果在某些条件下,需要安装Sun (Oracle)的Java,则需要自己手工安装. 一般情 ...

  7. ubuntu14.04 下手动安装java jdk

    ubuntu14.04 下手动安装java jdk 第一步: 下载jdk.tar.gz (这里假设下载的文件名为jdk.tar.gz) 第二步: 解压 sudo tar -zxvf ./jdk.tar ...

  8. 【linux】linux下准确查询正在tomcat下运行的java进程。准确获取正在运行的java进程的PID

    准确获取定位到tomcat下正在运行的java进程的PID命令: ps -ef|grep java | grep catalina | awk '{print $2}' 准确定位到tomcat下正在运 ...

  9. 【Hadoop】HA 场景下访问 HDFS JAVA API Client

    客户端需要指定ns名称,节点配置,ConfiguredFailoverProxyProvider等信息. 代码示例: package cn.itacst.hadoop.hdfs; import jav ...

随机推荐

  1. react基础语法(五) state和props区别和使用

    props的验证: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> < ...

  2. 关于maven source1.5报错

    是因为maven 默认是1.5编译的 <build>//加上这个配置,把编译给改掉试试 <pluginManagement> <plugins> <plugi ...

  3. 洛谷 P2319 [HNOI2006]超级英雄

    题目描述 题目描述 现在电视台有一种节目叫做超级英雄,大概的流程就是每位选手到台上回答主持人的几个问题,然后根据回答问题的多少获得不同数目的奖品或奖金.主持人问题准备了若干道题目,只有当选手正确回答一 ...

  4. CSS 功能简介

    CSS的功能主要包括节点管理(Node Management,以下简称NM)和组管理(Group Management,以下简称GM)两部分,都是由守护进程ocssd.bin 来实现的,这是个多线程的 ...

  5. springBoot + KISSO实现单点登录

    1:创建一个maven项目 kisso,然后再创建二个子项目都是springboot 2:二个boot项目的pom.xml都是一样的 就这三个依赖,3:接下来就是码代码了,首先在(在我这里)sprin ...

  6. ElasticSearch的常用方法

    关键词  cluster  集群  shards  索引分片    replicas  索引的副本    recovery  数据重新分布 gateway  索引的持久化方式 Transport 交互 ...

  7. vs2010的资源视图中,对话框显示数字的解决方法之一

    以上是不正常显示. 我这次遇到该问题的原因是资源名IDD_DLG_INTENSITY重复定义导致的, 所以在resource.h文件中去除重复定义就好了. 正常应该显示DD_XXX,如下图所示

  8. GCC、g++编译器和gcc编译器的区别

    GCC:(GNU Compiler Collection,GNU编译器套件),是由 GNU 开发的编程语言编译器.它是以GPL许可证所发行的自由软件,也是 GNU计划的关键部分. gcc:GNU的C语 ...

  9. 【原创翻译】链接DLL至可执行文件---翻译自MSDN

    可执行文件.exe链接(或加载)DLL有以下两种形式: 隐式链接 显式链接 隐式链接是指静态加载或在程序加载时动态链接. 通过隐式链接,在使用DLL时,可执行文件链接到一个由生成DLL的人提供的导入函 ...

  10. spring注解开发-IOC

    1. @Configuration, @Bean @Configuration该注解就是用来告诉spring这是配置类 @Bean该注解是用来注册一个bean.类型是返回值的类型,ID默认是用方法名作 ...