一、介绍

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

二、特点

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

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

三、结构

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

举例如下:

//要生成的类Person
message Person {
required string name = 1;
required int32 id = 2;
optional string email = 3;
enum PhoneType {
MOBILE = 0;
HOME = 1;
WORK = 2;
}
message PhoneNumber {
required string number = 1;
optional PhoneType type = 2 [default = HOME];
}
repeated PhoneNumber phone = 4; }

(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

写的内容举例如下:

syntax = "proto2";

//生成的类会放在protoc.exe同目录下的tutorial
//如果.proto文件中写了java_package,就以java_package为准。
package beans;
//生成的类会放在protoc.exe同目录下的com.proto.tutorial下
//option java_package = "com.proto.tutorial";
//最终成的类名
//option java_outer_classname = "AddressBookProtos"; message Person { required string name = 1; required int32 id = 2; . optional string email = 3; enum PhoneType { MOBILE = 0; HOME = 1; WORK = 2; } message PhoneNumber { required string number = 1; optional PhoneType type = 2 [default = HOME]; } repeated PhoneNumber phone = 4; } message AddressBook { repeated Person person = 1;
package tutorial; option java_package = "com.proto.tutorial"; option java_outer_classname = "AddressBookProtos"; message Person { required string name = 1; required int32 id = 2; // Unique ID number for this person. optional string email = 3; enum PhoneType { MOBILE = 0; HOME = 1; WORK = 2; } message PhoneNumber { required string number = 1; optional PhoneType type = 2 [default = HOME]; } repeated PhoneNumber phone = 4; } message AddressBook { repeated Person person = 1; }

3、将.proto文件转成Java类

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

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
ources/proto/AddressBook.proto protoc.exe -I=(proto文件所在绝对路径,不包括proto文件本身)  --java_out=(文件输出目录) (proto文件所在绝对路径,包括proto文件名)

4、相关包

<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>3.7.1</version>
</dependency> <dependency>
<groupId>com.googlecode.protobuf-java-format</groupId>
<artifactId>protobuf-java-format</artifactId>
<version>1.2</version>
</dependency>

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

需要安装Protobuf Support插件,

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

输入Protobuf,点击install

6、具体使用举例

AddressBookProtos.AddressBook .Builder  addressBook= AddressBookProtos.AddressBook .newBuilder();
AddressBookProtos.Person .Builder person= AddressBookProtos.Person .newBuilder();
person.setName("Mike");
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. SQL Server2012 T-SQL对分页的增强尝试

    简介 SQL Server 2012中在Order By子句之后新增了OFFSET和FETCH子句来限制输出的行数从而达到了分页效果.相比较SQL Server 2005/2008的ROW_Numbe ...

  2. SPICE-HTML5 鼠标指针BUG修复

    研究SPICE,找到了他们官方指定的HTML5客户端.下载下来用一下,发现跟网页VNC的水平差不多了.http://www.spice-space.org/page/Html5 服务端直接用QEMU起 ...

  3. oracle补丁类型

    名称 说明 Release ¤ 标准产品发布.如Oracle Database 10g Release 2的第一个发行版本为10.2.0.1,可以在OTN.edelivery等站点上公开下载 Patc ...

  4. DROP TABLE - 删除一个表

    SYNOPSIS DROP TABLE name [, ...] [ CASCADE | RESTRICT ] DESCRIPTION 描述 DROP TABLE 从数据库中删除表或视图. 只有其所有 ...

  5. uva1614 Hell on the Markets

    贪心部分的理论依据:前i个数可以凑出1-sum[i]的所有整数. 证明:第二类数学归纳,n=1时成立,假设n=k之前所有项都成立,当n=k+1时.sum[k+1]=sum[k]+a[k+1].只需证明 ...

  6. 最短路 || POJ 2387 Til the Cows Come Home

    从点N到1的最短路 *记得无向图两个方向都要建边就好了…… 以及多组数据= = #include <iostream> #include <cstdio> #include & ...

  7. Spring-01 注解实现IOC

    Spring框架四大原则 使用pojo进行轻量级和最小侵入式开发. 通过依赖注入和基于接口编程实现松耦合. 使用AOP和默认习惯进行声明式编程. 使用AOP和模板(template)减少模式化代码. ...

  8. <c:forEach>实例演示

    <c:forEach>实例演示 <%@ page language="java" contentType="text/html; charset=UTF ...

  9. springmvc @RequestParam @RequestBody @PathVariable 等参数绑定注解详解

    简介: handler method 参数绑定常用的注解,我们根据他们处理的Request的不同内容部分分为四类:(主要讲解常用类型) A.处理requet uri 部分(这里指uri templat ...

  10. 洛谷——P4932 浏览器

    P4932 浏览器 __stdcall给了你n个点,第i个点有权值x[i],对于两个点u和v,如果x[u] xor x[v]的结果在二进制表示下有奇数个1,那么在u和v之间连接一个Edge,现在__s ...