微信扫一扫

028-83195727 , 15928970361
business@forhy.com

Google Protocol Buffer序列化入门实战(附源码)

pb2016-08-10

Google Protocol Buffer入门实战(附源码)

Google Protocol Buffer(后面简称PB)是Google开源的一款二进制序列化工具,占用空间小,传输效率高。最近由于项目中使用到了PB,所以特地学习了PB,这篇文章也是自己学习PB的一些小结。

根据官方定义,PB是一个语言中立,平台中立的,用于序列化结构化数据的协议。

说到序列化,可能大家最容易想到的是JDK自带的序列化协议,使用PB而不使用自带的序列化协议主要基于以下几点考虑:

  • 占用空间希望尽可能小
  • 传输效率尽可能高
  • 跨平台

那么,JDK自带的序列化就不能满足需求了,而且PB将数据序列化成二进制数据,大大降低空间占用。PB的优势主要体现在以下几点:

  • 更简单
  • 降低3-10倍的占用空间
  • 20至100倍的速度提升
  • 低侵入性
  • 更易于编程的数据访问类

PB入门实战

使用PB也是极其简单的,首先需要定义一个后缀为.proto的文件,然后使用PB编译器生成数据访问类,使用PB的API读写数据。需要下载PB编译器执行编译,然后在IDE中下载PB插件。

以IntelliJ IDEA为例,可以安装Google Protocol Buffers support插件,在Plugins栏目中选择Browse repositories,在搜索框中搜索Google Protocol Buffers support,出现下图,点击安装,之后重启IDEA就可以了。

创建Maven工程,配置PB编译器的安装路径(文后有下载地址):

pom.xml依赖文件:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.rhwayfun</groupId>
    <artifactId>protocol-buffer-demo</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <dependency>
            <groupId>com.google.protobuf</groupId>
            <artifactId>protobuf-java</artifactId>
            <version>2.5.0</version>
        </dependency>
    </dependencies>
</project>

安装之后就需要编写.proto的文件了,作为示例,代码如下:

package com.rhwayfun.demo;

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;
}

因为是Maven工程,因此需要配置PB编译器的编译路径,在IDEA中配置如下:

使用PB编译器编译后的结果如下:

// Generated by the protocol buffer compiler.  DO NOT EDIT!
// source: PersonMessage.proto

package com.rhwayfun.demo;

public final class PersonMessage {
  private PersonMessage() {}
  public static void registerAllExtensions(
      com.google.protobuf.ExtensionRegistry registry) {
  }
  public interface PersonOrBuilder extends
      // @@protoc_insertion_point(interface_extends:com.rhwayfun.demo.Person)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>required string name = 1;</code>
     */
    boolean hasName();
    /**
     * <code>required string name = 1;</code>
     */
    java.lang.String getName();
    /**
     * <code>required string name = 1;</code>
     */
    com.google.protobuf.ByteString
        getNameBytes();

    /**
     * <code>required int32 id = 2;</code>
     */
    boolean hasId();
    /**
     * <code>required int32 id = 2;</code>
     */
    int getId();

    /**
     * <code>optional string email = 3;</code>
     */
    boolean hasEmail();
    /**
     * <code>optional string email = 3;</code>
     */
    java.lang.String getEmail();

    // 此处省略其他代码

编写测试代码如下:

package com.rhwayfun.demo;

import org.junit.Test;

import static org.junit.Assert.*;

/**
 * @Description: PersonOuterClassTest
 * @author: ZhongCB
 * @date: 2016/08/09
 */
public class PersonMessageTest {

    @Test
    public void testMakeInstance(){
        PersonMessage.Person person = PersonMessage.Person.newBuilder().setId(1)
                .setEmail("rhwayfun@163.com")
                .setName("rhwayfun").build();
        assertEquals(person.getName(), "rhwayfun");
        assertEquals(person.getEmail(), "rhwayfun@qq.com");
    }
}

最后的运行结果如下:

附源码和PB编译器下载地址:下载地址