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.grpc</groupId>
    <artifactId>grpc-all</artifactId>
    <version>1.30.1</version>
  </dependency>
</dependencies>
<build>
  <!--这个是为了下载下面的工具用的,他可以提供一些变量,os.detected.classifier变量可以根据当前系统的类型来下载对应的工具-->
  <extensions>
    <extension>
      <groupId>kr.motd.maven</groupId>
      <artifactId>os-maven-plugin</artifactId>
      <version>1.6.2</version>
    </extension>
  </extensions>
  <plugins>
    <plugin>
      <groupId>org.xolstice.maven.plugins</groupId>
      <artifactId>protobuf-maven-plugin</artifactId>
      <version>0.5.0</version>
      <!--添加.proto文件的编译工具-->
      <configuration>
        <!--protoc工具通过.proto文件生成对应的java对应的类-->
        <protocArtifact>com.google.protobuf:protoc:3.0.0-beta-4:exe:${os.detected.classifier}
        </protocArtifact>
        <!--protoc-gen-grpc-java工具通过.proto文件生成grpc工具类-->
        <pluginArtifact>io.grpc:protoc-gen-grpc-java:0.15.0:exe:${os.detected.classifier}</pluginArtifact>
        <!--这是生成grpc工具类存放的文件夹的名字-->
        <pluginId>grpc</pluginId>
        <!--要编译的.proto文件的路径-->
        <protoSourceRoot>src/main/resources/proto</protoSourceRoot>
      </configuration>
      <executions>
        <!--这是上面两个编译工具用到的命令-->
        <execution>
          <goals>
            <goal>compile</goal>
            <goal>compile-custom</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>

引入依赖之后,运行 maven 插件。
在这里插入图片描述
运行结束之后在 target 目录下可以看到生成的 java 文件。
在这里插入图片描述

编译工具

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

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

-I 指.proto 文件所在目录,**–java_out **指生成的 java 文件所在的目录,后面紧跟.proto 文件。这样生成的文件如下图:
在这里插入图片描述

编写测试代码

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("hanxin@proto.com")
        .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 文件,内容如下:


七七的通讯录<韩信hanxin@proto.com"
17500001111"
18900002222
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值