Protocol Buffers 浅析

来源:互联网 发布:网络税务学校 编辑:程序博客网 时间:2024/06/14 12:08

简介

Protocol Buffers(简称protobuf)是谷歌的一项技术,用于将结构化的数据序列化、反序列化,经常用于网络传输。
这货实际上类似于XML生成和解析,但protobuf的效率高于XML,不过protobuf生成的是字节码,可读性比XML差。类似的还有json、Java的Serializable等。
详细了解可以参考Protocol Buffers,接下类将介绍一些基本的使用步骤。

使用

首先通读Protocol Buffers,了解.proto文件的基本格式和写法,下载官方给我们准备的工具,通过该工具可以将.proto文件直接生成需要的代码源文件(比如Java/C/C++/Python等等),接下来直接将该源文件放到工程目录中,编写相应的序列化和反序列化等,这样就完成了整个流程,下面给出简单的实现步骤。

.proto文件

time.proto

option java_package = "com.test.app.pb.common";option java_outer_classname = "TimeProto";message Time {    optional int32 id = 1;    optional int32 startTime = 2;    optional int32 endTime = 3;    optional int64 systemTime = 4;    optional string countDownTip = 5;    optional int32 sEffectiveTime = 6;    optional int32 eEffectiveTime = 7;    optional string  startTip = 8;    optional string endTip = 9;}

上面的1、2、3、4是unique numbered tag,是一个唯一标识。这也是整个编码中的亮点,想一探究竟的可以继续往下看。

通过工具生成代码

protoc工具使用的一般格式是:

protoc -I=$SRC_DIR --java_out=$DST_DIR $SRC_DIR/xxx.protoprotoc -I=$SRC_DIR --cpp_out=$DST_DIR $SRC_DIR/xxx.proto

其中SRC_DIRproto文件所在的目录,DST_DIR是编译proto文件后生成的结构体处理文件的目录

之后会生成对结构体time.proto中描述的各字段做序列化反序列化的类。
工具命令如下:
此处输入图片的描述
生成的java代码
此处输入图片的描述

写测试代码

将上面生成的代码加入到工程中去,再将Jar包导入工程中,或者添加如下Maver依赖

<dependency>      <groupId>com.google.protobuf</groupId>      <artifactId>protobuf-java</artifactId>      <version>2.6.1</version>  </dependency>  

接下来写测试代码

序列化代码(发送方)

TimeProto.Time.Builder timeBuilder = TimeProto.Time.newBuilder();        timeBuilder.setEEffectiveTime(20160428)                   .setEndTime(20160429)                   .setEndTip("End")                   .setSEffectiveTime(20160428)                   .setStartTime(20160426)                   .setStartTip("Start")                   .setSystemTime(20160428);        TimeProto.Time time = timeBuilder.build();        ByteArrayOutputStream output = new ByteArrayOutputStream();          try {            time.writeTo(output);        } catch (IOException e) {            e.printStackTrace();        }

反序列化(接收方)

try {    HttpClient httpClient = new DefaultHttpClient();    url = NetworkUtils.getCompleteUrl(url, getParams);    HttpGet request = new HttpGet(url);    HttpResponse response = httpClient.execute(request);    ByteArrayBuffer buffer = new ByteArrayBuffer(32 * 1024);    InputStream in = null;    try {        HttpEntity entity = response.getEntity();        if (entity == null) {        } else {            in = response.getEntity().getContent();        }        int temp;        byte[] bytes = new byte[8096];        while ((temp = in.read(bytes)) != -1) {            buffer.append(bytes, 0, temp);        }    } catch (SocketTimeoutException e) {        throw new HttpException(HttpException.MSG_NETWORK_ERROR, e);    } catch (IOException e) {        throw new HttpException(HttpException.MSG_NETWORK_ERROR, e);    } finally {        if (in != null) {            try {                in.close();            } catch (IOException e) {                e.printStackTrace();            }        }    }    byte[] result = buffer.toByteArray();    try {        TimeProto.Time timeResp = TimeProto.Time.parseFrom(result);    } catch (InvalidProtocolBufferException e) {        e.printStackTrace();    }} catch (SocketTimeoutException e) {    throw new HttpException(HttpException.MSG_NETWORK_ERROR, e);} catch (IllegalStateException e) {    throw new HttpException(HttpException.MSG_NETWORK_ERROR, e);} catch (IOException e) {    throw new HttpException(HttpException.MSG_NETWORK_ERROR, e);}

关键的逻辑在L33到L35行,拿到字符数组以后直接parse出来。

参考文档:
Protocol Buffers 官方文档
Java使用Protocol Buffers入门四步骤 如何使用
google protobuf源码分析1源码分析
Protocol Buffer技术详解(Java实例) 如何使用
玩转Protocol Buffers 如何使用
Google Protocol Buffer 的使用和原理 原理和使用
Why Protocol Buffer So Fast? —-protobuf编码详解 原理和使用
Protocol Buffers编码详解,例子,图解 原理和使用

0 0
原创粉丝点击