1.简介

Protocol Buffers是Google开发一种数据描述语言,能够将数据进行序列化,可用于数据存储、通信协议等方面.

可以理解成更快、更简单、更小的JSON或者XML,区别在于Protocol Buffers是二进制格式,而JSON和XML是文本格式.

相对于XML,Protocol Buffers有如下几个优点:

1.简洁

2.体积小,消息大小只有XML的1/10到1/3.

3.速度快,解析速度比XML快20~100倍.

4.使用Protocol Buffers的编译器,可以生成更容易在编程中使用的数据访问代码.

5.更好的兼容性,Protocol Buffers设计的一个原则就是要能够很好的支持向下或向上兼容.

 

使用不同数据描述语言所序列化成字节的个数比对:

 

使用不同数据描述语言在网络中进行数据的传输时,序列化以及反序列化的速度比对:

 

 

 

2.proto文件的语法规则 

 

1.使用message关键字定义消息,并指定消息的名称(取一个有意义的名字)

2.指定字段的类型和名称

3.添加字段的约束

4.定义字段的编号(从1开始,其中19000~19999被Protocol Buffers作为保留字段)

 

 最基本的message

message User{
    required int32 id = 1;
    required string username = 2;
    required string password = 3;
    optional string email = 4;
}

 

字段类型

字段约束

required指定该字段必须赋值

optional表示该字段允许为空,可以使用[default]指定默认值,如果没有指定默认值则会使用字段类型的默认值.

repeated指定字段为集合.

oneof指定一组字段中必须有一个字段要赋值.

 

*在一个proto文件中可以同时定义多个message类型,生成代码时根据生成代码的目标语言不同,处理的方式不太一样(Java会针对每个message类型生成一个.java文件).

message User{
    required int32 id = 1;
    //username或email之间必须有一个字段要赋值
    oneof login{
      string username = 3;
      string email = 4;
    }
    required string password = 2;
}

message Admin{
    required int32 id = 1;
    required string username = 2;
    required string password = 3;
}

 

*可以指定字段的类型为其他的message类型.

message Course{
    required User user = 1;
    required string cour_name = 2; 
}

message User{
    required int32 id = 1;
    required string username = 2;
    required string password = 3;
    optional string email = 4;
}

 

*在proto文件中支持类型的嵌套,即定义的message类型仅作为包含其message类型的字段类型.

message Course{
    message User{
        required int32 id = 1;
        required string username = 2;
        required string password = 3;
        optional string email = 4;
    }
    required User user = 1;
    required string cour_name = 2; 
}

 

*使用extensions关键字预留消息类型的字段编号,通过extend关键字继续定义.

message User{
    //30~100编号为User类型私有.
    extensions 30 to 100
}

extend User{
    required int32 id = 1;
    required string username = 2;
    required string password = 3;
    optional string email = 4;
}

 

*可以使用import关键字导入其他proto文件.

*可以使用option java_package设置生成java类的包名.

*可以使用option java_outer_classname设置生成java类的类名.

import "other.proto"
option java_package = "com.zht.protobuf";
option java_outer_classname = "UserModel";
message User{
    required int32 id = 1;
    required string username = 2;
    required string password = 3;
    optional string email = 4;
}

  

3.protobuf的使用

 

1.环境的准备

 

在github下载对应操作环境的protobuf工具包: https://github.com/google/protobuf/releases

windows用户选择: protoc-3.5.1-win32.zip

解压后配置环境变量PATH,使其在上下文能直接搜索 protoc.exe.

 

2.编写.proto文件

 

E:\proto\user.proto

内容如下:

syntax = "proto2";
option java_package = "com.zht.protobuf";
option java_outer_classname = "UserModel";
message User{
    required int32 id = 1;
    required string username = 2;
    required string password = 3;
    optional string email = 4;
}

 

3.使用protoc.exe命令生成实体

 

protoc.exe -I [proto文件所在目录] –java_out  [JAVA类存放目录]  [proto文件绝对路径]

 

 

 

 

4.将实体放入工程进行实体的构造和赋值

 

将实体放入工程:

 

构造并且赋值:

public class Main {

    public static void main(String[] args) throws InvalidProtocolBufferException {
        //获取构造器并进行赋值
        UserModel.User.Builder builder = UserModel.User.newBuilder();
        builder.setId(1);
        builder.setUsername("zhuanght");
        builder.setPassword("123456");
        builder.setEmail("aiuzht119@163.com");
        
        //获取实体
        UserModel.User user = builder.build();
        
        System.out.println("源数据:\r"+ user.toString());
        System.out.println("序列化后:"+Arrays.toString(user.toByteArray()));

        //模拟接收Byte[],反序列化成User实体
        byte[] data =user.toByteArray();
        User u = User.parseFrom(data);
        System.out.println("\r解析:\r" +u.toString());
    }
    
}

 

打印结果 :

源数据:
id: 1
username: "zhuanght"
password: "123456"
email: "aiuzht119@163.com"

序列化后:[8, 1, 18, 8, 122, 104, 117, 97, 110, 103, 104, 116, 26, 6, 49, 50, 51, 52, 53, 54, 34, 17, 97, 105, 117, 122, 104, 116, 49, 49, 57, 64, 49, 54, 51, 46, 99, 111, 109]

解析:
id: 1
username: "zhuanght"
password: "123456"
email: "aiuzht119@163.com"

  

5.获取序列化后的字节数组在网络中进行传输

 

版权声明:本文为funyoung原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/funyoung/p/8645562.html