Protobuf 了解一下

ProtoBuf 使用

ProtoBuf 全称 protocol buffers,是 google 开源的一个平台无关、语言无关的序列化框架。
官网点击这里 protobuf 官网


文本通过一个简单的案例介绍 protobuf 的简单使用。

创建 addressbook.proto 文件

创建一个 maven 项目,在 resources 下创建一个目录 proto (可自己更改),然后在该目录下创建一个 addressbook.proto 文件。

syntax = "proto3";

package tutorial;

option java_package = "protobuf.demo.tutorial";
option java_outer_classname = "AddressBookProto";

message Person{
  int32 id = 1;
  string name = 2;
  string email = 3 ;

  enum PhoneType{
    MOBILE = 0;
    HOME = 1;
    WORK = 2;
  }

  message PhoneNumber{
    string number = 1;
    PhoneType type = 2;
  }

  repeated PhoneNumber phones = 4;
}

message AddressBook{
  string bookName = 1;
  repeated Person people = 2;
}

syntax 定义 .proto 文件使用的是 proto3 的语法。proto2 和 proto3 的语法区别可以去官网查看。
package 指的是该 .proto 文件里定义的类的包路径。
option java_package指的最终生成的 java 类所在的包名。
option java_outer_classname指的是最终生成的 java 类的名称。
message指的定义的消息类。
enum 定义枚举类。
repeated 指明该字段可以重复添加,在 java 看来该字段是一个 list 集合。

生成 java 类

生成 java 类的方式有很多种,这里用列举两种方式。

maven 插件

编写 maven pom 文件,新增如下内容。

<dependencies>
  <dependency>
    <groupId>io.grpcgroupId>
    <artifactId>grpc-allartifactId>
    <version>1.30.1version>
  dependency>
dependencies>
<build>
  
  <extensions>
    <extension>
      <groupId>kr.motd.mavengroupId>
      <artifactId>os-maven-pluginartifactId>
      <version>1.6.2version>
    extension>
  extensions>
  <plugins>
    <plugin>
      <groupId>org.xolstice.maven.pluginsgroupId>
      <artifactId>protobuf-maven-pluginartifactId>
      <version>0.5.0version>
      
      <configuration>
        
        <protocArtifact>com.google.protobuf:protoc:3.0.0-beta-4:exe:${os.detected.classifier}
        protocArtifact>
        
        <pluginArtifact>io.grpc:protoc-gen-grpc-java:0.15.0:exe:${os.detected.classifier}pluginArtifact>
        
        <pluginId>grpcpluginId>
        
        <protoSourceRoot>src/main/resources/protoprotoSourceRoot>
      configuration>
      <executions>
        
        <execution>
          <goals>
            <goal>compilegoal>
            <goal>compile-customgoal>
          goals>
        execution>
      executions>
    plugin>
  plugins>
build>

引入依赖之后,运行 maven 插件。
Protobuf 了解一下_第1张图片
运行结束之后在 target 目录下可以看到生成的 java 文件。
Protobuf 了解一下_第2张图片

编译工具

去官网下载最新的编译工具,传送门点这里。根据自己的操作系统下载。然后运行如下命令:

protoc -I=./src/main/resources/proto/ --java_out=./src/main/java ./src/main/resources/proto/addressbook.proto 

-I 指.proto 文件所在目录,**–java_out **指生成的 java 文件所在的目录,后面紧跟.proto 文件。这样生成的文件如下图:
Protobuf 了解一下_第3张图片

编写测试代码

main 方法如下:

public static void main(String[] args) throws IOException {
    File file = new File("address_book.txt");
    if (!file.exists() && file.createNewFile()) {
        System.out.println("创建了一个新的通讯录" + file.getName());
    }
    System.out.println("开始新增人员信息");
    writeAddressBook(file);
    System.out.println("--------------");
    System.out.println("开始读取人员信息");
    readAddressBook(file);
    System.out.println("--------------");
}

生成一个文件,然后写入一个人员信息,再从文件中读取出来。

private static void writeAddressBook(File file) throws IOException {
    FileOutputStream outputStream = new FileOutputStream(file);
    // 创建一个手机号码
    AddressBookProto.Person.PhoneNumber.Builder builder = AddressBookProto.Person.PhoneNumber.newBuilder();
    AddressBookProto.Person.PhoneNumber phoneNumber1 = builder
        .setNumber("17500001111")
        .setType(AddressBookProto.Person.PhoneType.MOBILE)
        .build();
    builder.clear();
    AddressBookProto.Person.PhoneNumber phoneNumber2 = builder
        .setNumber("18900002222")
        .setType(AddressBookProto.Person.PhoneType.WORK)
        .build();
    // 创建一个人 韩信
    AddressBookProto.Person hanXin = AddressBookProto.Person.newBuilder()
        .setId(1)
        .setName("韩信")
        .setEmail("[email protected]")
        .addPhones(phoneNumber1)
        .addPhones(phoneNumber2)
        .build();
    System.out.println("新增通讯录人员信息成功");
    // 将 七七这个人的信息添加到通讯录
    AddressBookProto.AddressBook addressBook = AddressBookProto.AddressBook.newBuilder()
        .setBookName("七七的通讯录")
        .addPeople(hanXin)
        .build();
    // 持久化
    outputStream.write(addressBook.toByteArray());
    outputStream.close();
}
private static void readAddressBook(File file) throws IOException {
    FileInputStream inputStream = new FileInputStream(file);
    AddressBookProto.AddressBook addressBook = AddressBookProto.AddressBook.parseFrom(inputStream);
    System.out.println(addressBook.getBookName() + ":");
    for (AddressBookProto.Person person : addressBook.getPeopleList()) {
        System.out.printf("编号:%d\t姓名:%s\n", person.getId(), person.getName());
        List<AddressBookProto.Person.PhoneNumber> phonesList = person.getPhonesList();
        System.out.printf("\t%s\t%s\n", "号码类型", "号码");
        for (AddressBookProto.Person.PhoneNumber phoneNumber : phonesList) {
            System.out.printf("\t%s\t%s\n", phoneNumber.getType(), phoneNumber.getNumber());
        }
    }
}

运行 main 方法,结果如下:

开始新增人员信息
新增通讯录人员信息成功
--------------
开始读取人员信息
七七的通讯录:
编号:1	姓名:韩信
	号码类型	号码
	MOBILE	17500001111
	WORK	18900002222
--------------

结果可以正常写入并读取出来,查看生成的address_book.txt 文件,内容如下:


七七的通讯录<韩信[email protected]"
17500001111"
18900002222

你可能感兴趣的:(Netty)