Protocol Buffers 浅析

###简介

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.proto
protoc -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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值