zoukankan      html  css  js  c++  java
  • Netty学习——Google Protobuf的初步了解

    学习参考的官网: https://developers.google.com/protocol-buffers/docs/javatutorial   

    简单指南详解:这个文档写的简直是太详细了。

    本篇从下面三个步骤进行介绍:

    详细内容,我就不做过多解释,自行查阅官方文档,在这只是记录,我觉得比较重要的东西,能够帮助我更好的理解。


    I.Define message formats in a .proto file.    

    syntax = "proto2";
    
    package tutorial; //包名
    
    option java_package = "com.example.tutorial";  //针对于java的包名
    option java_outer_classname = "AddressBookProtos"; //这个文件,最终都会被包裹在这个类内,下面的类算是这个类的内部类
    
    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];  // optional类型 和定义默认值
      }
    
      repeated PhoneNumber phones = 4;
    }
    
    message AddressBook {
      repeated Person people = 1;  //repeated类型,其实就相当于java的ArrayList,用来
    }

    其他需要注意的点:

    1.对于前两个字段java_package  和 package ,就是说,可以不写java_package,会默认 调用package ,写了java_package,java就会识别这个,但是就算写了java_package,也要package ,是为了其他语言能够有包名能够使用

    2.这个数字,=1, =2 ,不是顺序,或者是赋值,只是每一个字段在Proto文件中,都会有一个唯一数字标识符

    3.对于以下的三种类型 required,optional,repeated  官方推荐,尽量不是用required,因为弊大于利。


    II. Use the protocol buffer compiler.

    需要注意的地方:

    使用PB编译器生成出的对象是不可变的,需要使用构建器的方法连模式(set.set.set )一个一个的去设置值,然后再需要最后使用build方法去完成整个对象的创建,如下介绍

    每一次set完之后的返回结果,都是另一个构建器,就是为了能够在一行代码上,完成对象的构建

    通过构建器的方法连模式,完成一个对象的创建和设置值的标准写法:如下

    Person john =
      Person.newBuilder()
        .setId(1234)
        .setName("John Doe")
        .setEmail("jdoe@example.com")
        .addPhones(
          Person.PhoneNumber.newBuilder()
            .setNumber("555-4321")
            .setType(Person.PhoneType.HOME))
        .build();

    Message除了自定义的属性之外,还提供的有几个默认的方法,让你能够检查和操作整个消息

    isInitialized()://检查是否所有的必备字段,都已经被设置值
    
    toString(): //返回一个人类可读的字符形式,通常用于调试
    
    mergeFrom()://(只有构建器才有)将另一个消息的内容,合并到当前消息当中并且覆盖之前的标量字段,合并复核的字段和重复的阻断,完成对象的合并
    
    clear()://(只有构建器才有) 恢复到原来属性都为空的这个状态

    解析和序列化这些消息

    byte[] toByteArray(); //将消息序列化,并返回了包含原生字节的一个字节数组,就是把消息本身转换成字节数组
    
    static Person parseFrom(byte[] data);//从给定的字节数组当中解析这条消息,将字节数组的内容转换成对象
    
    void writeTo(OutputStream output);//将消息序列化,并输出到一个输出流当中,
    
    static Person parseFrom(InputStream input); //接着读取输入流中的消息并进行解析

    注意:不能通过继承的方式,给这个对象添加更多的行为。

    如果想要给这个message对象赋予响应的方法,可以借助使用多个message合并的方式来实现功能而并不是通过继承的方式

     


    III. Use the Java protocol buffer API to write and read messages.

    Writer a Message 

    import com.example.tutorial.AddressBookProtos.AddressBook;
    import com.example.tutorial.AddressBookProtos.Person;
    import java.io.BufferedReader;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.InputStreamReader;
    import java.io.IOException;
    import java.io.PrintStream;
    
    class AddPerson {
      // This function fills in a Person message based on user input.
      static Person PromptForAddress(BufferedReader stdin,
                                     PrintStream stdout) throws IOException {
        Person.Builder person = Person.newBuilder();
    
        stdout.print("Enter person ID: ");
        person.setId(Integer.valueOf(stdin.readLine()));
    
        stdout.print("Enter name: ");
        person.setName(stdin.readLine());
    
        stdout.print("Enter email address (blank for none): ");
        String email = stdin.readLine();
        if (email.length() > 0) {
          person.setEmail(email);
        }
    
        while (true) {
          stdout.print("Enter a phone number (or leave blank to finish): ");
          String number = stdin.readLine();
          if (number.length() == 0) {
            break;
          }
    
          Person.PhoneNumber.Builder phoneNumber =
            Person.PhoneNumber.newBuilder().setNumber(number);
    
          stdout.print("Is this a mobile, home, or work phone? ");
          String type = stdin.readLine();
          if (type.equals("mobile")) {
            phoneNumber.setType(Person.PhoneType.MOBILE);
          } else if (type.equals("home")) {
            phoneNumber.setType(Person.PhoneType.HOME);
          } else if (type.equals("work")) {
            phoneNumber.setType(Person.PhoneType.WORK);
          } else {
            stdout.println("Unknown phone type.  Using default.");
          }
    
          person.addPhones(phoneNumber);
        }
    
        return person.build();
      }
    
      // Main function:  Reads the entire address book from a file,
      //   adds one person based on user input, then writes it back out to the same
      //   file.
      public static void main(String[] args) throws Exception {
        if (args.length != 1) {
          System.err.println("Usage:  AddPerson ADDRESS_BOOK_FILE");
          System.exit(-1);
        }
    
        AddressBook.Builder addressBook = AddressBook.newBuilder();
    
        // Read the existing address book.
        try {
          addressBook.mergeFrom(new FileInputStream(args[0]));
        } catch (FileNotFoundException e) {
          System.out.println(args[0] + ": File not found.  Creating a new file.");
        }
    
        // Add an address.
        addressBook.addPerson(
          PromptForAddress(new BufferedReader(new InputStreamReader(System.in)),
                           System.out));
    
        // Write the new address book back to disk.
        FileOutputStream output = new FileOutputStream(args[0]);
        addressBook.build().writeTo(output);
        output.close();
      }
    }

    Reader a Message

    import com.example.tutorial.AddressBookProtos.AddressBook;
    import com.example.tutorial.AddressBookProtos.Person;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.PrintStream;
    
    class ListPeople {
      // Iterates though all people in the AddressBook and prints info about them.
      static void Print(AddressBook addressBook) {
        for (Person person: addressBook.getPeopleList()) {
          System.out.println("Person ID: " + person.getId());
          System.out.println("  Name: " + person.getName());
          if (person.hasEmail()) {
            System.out.println("  E-mail address: " + person.getEmail());
          }
    
          for (Person.PhoneNumber phoneNumber : person.getPhonesList()) {
            switch (phoneNumber.getType()) {
              case MOBILE:
                System.out.print("  Mobile phone #: ");
                break;
              case HOME:
                System.out.print("  Home phone #: ");
                break;
              case WORK:
                System.out.print("  Work phone #: ");
                break;
            }
            System.out.println(phoneNumber.getNumber());
          }
        }
      }
    
      // Main function:  Reads the entire address book from a file and prints all
      //   the information inside.
      public static void main(String[] args) throws Exception {
        if (args.length != 1) {
          System.err.println("Usage:  ListPeople ADDRESS_BOOK_FILE");
          System.exit(-1);
        }
    
        // Read the existing address book.
        AddressBook addressBook =
          AddressBook.parseFrom(new FileInputStream(args[0]));
    
        Print(addressBook);
      }
    }
  • 相关阅读:
    apache设置无缓存
    唤醒键盘时取消对特定类的position:fixed定位
    vscode增加sftp扩展
    浮层蒙版加载中实现方式
    管理应用程序版本Elastic Beanstalk
    向 Elastic Beanstalk 环境中添加数据库
    在 Amazon ECS 上运行 X-Ray 守护程序
    SNS Message Attributes
    ProvisionedThroughputExceededException
    使用 Amazon CloudWatch Events 检测和响应管道状态更改
  • 原文地址:https://www.cnblogs.com/bigbaby/p/11972417.html
Copyright © 2011-2022 走看看