Protobuf和Java

Protobuf简介

Protobuf是Google开源的二进制序列化数据协议。具有语言和平台无关性,支持多种语言接口。

Protobuf的优点:

1,通用性:多种语言支持
2,速度快:较比其他序列化格式如Json,XML编解码速度更快
3,小:因为是二进制格式,所以更小

缺点:

1,没有自描述性:因为是二进制,内容经过编码

Protobuf语法

Protobuf定义的数据格式类似于Java中的entity,而且使用protoc库可以把它转化成Java的Entity。

Protobuf定义一个数据的属性,转化成的Java类会自动添加其Getter和Setter方法以及其他辅助方法。

Protobuf的一个数据类成为message,protobuf有类似于C语言的数据类型,与其他语言的基本数据类型可以一一对应,如下:
这里写图片描述

Protobuf的数据可以设置为:requiredoptionalrepeated

required是必须存在字段,optional是可选字段,可以为空;repeated是可重复字段,转化成Java是一个List,可以存放0个,1个或多个元素。

每一个字段有一个整数唯一标识,感觉就像一个map的Key值。

Protobuf支持嵌套,即message套message。

以下例子可以阐述以上的所有规则:

message SearchResponse {
  message Result {
    required string url = 1;
    optional string title = 2;
    repeated string snippets = 3;
  }
  repeated Result result = 1;
}

Protobuf的应用实例

举一个例子来阐述protobuf-Java从头到尾的使用过程。

首先需要下载protobuf源代码,我选择2.5.0

下载下来的源代码根据README里面的内容进行安装。进入java文件夹,java的源码是一个maven项目,根据里面的README.txt可以进行maven安装或非maven安装,安装后在target文件夹中有protobuf-java-2.5.0.jar,这就是我们在Java项目中用来序列和反序列化protobuf数据的依赖包。

使用IDE创建一个测试的MAVEN项目,目录结构如下图:

这里写图片描述

在pom.xml添加依赖:

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

会自动导入jar包;或者手动将上面说的protobuf-java-2.5.0.jar加到项目中。

写proto

message Person {

    // ID(必需)
    required int32 id = 1;

    // 姓名(必需)
    required string name = 2;

    // email(可选)
    optional string email = 3;

    // 朋友(集合)
    repeated string friends = 4;
}

在命令行使用protoc命令将.proto编译成java类:

protoc --java_out=$DST_DIR $SRC_DIR/Person.proto

DSTDIRjava SRC_DIR是proto文件所在路径。将生成的java类放到项目的java文件夹下。

创建main类

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.List;

public class Main {

    public static void main(String[] args) throws IOException {

        // 按照定义的数据结构,创建一个Person
        PersonMsg.Person person = PersonMsg.Person.newBuilder()
            .setId(1)
            .setName("wayblink")
            .setEmail("xxx@gmail.com")
            .addFriends("Zhang 3")
            .addFriends("Li 4").build();

        // 将数据写到输出流,如网络输出流,这里就用ByteArrayOutputStream来代替
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        person.writeTo(output);

        // -------------- 分割线:上面是发送方,将数据序列化后发送 ---------------

        byte[] byteArray = output.toByteArray();

        // -------------- 分割线:下面是接收方,将数据接收后反序列化 ---------------

        // 接收到流并读取,如网络输入流,这里用ByteArrayInputStream来代替
        ByteArrayInputStream input = new ByteArrayInputStream(byteArray);

        // 反序列化
        PersonMsg.Person person2 = PersonMsg.Person.parseFrom(input);
        System.out.println("ID:" + person2.getId());
        System.out.println("name:" + person2.getName());
        System.out.println("email:" + person2.getEmail());
        System.out.println("friend:");
        List<String> friends = person2.getFriendsList();
        for(String friend : friends) {
            System.out.println(friend);
        }
    }

}

Proto的序列化与反序列化方法都在这个main方法中了。

运行:

ID:1
name:wayblink
email:xxx@gmail.com
friend:
Zhang 3
Li 4
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值