前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Netty系列化之Google Protobuf编解码

Netty系列化之Google Protobuf编解码

作者头像
黑洞代码
发布2021-01-14 15:38:50
1.1K0
发布2021-01-14 15:38:50
举报
文章被收录于专栏:落叶飞翔的蜗牛

内容目录

Protobuf 简介Protobuf 下载Protobuf 安装编写message.proto文件编译message.proto文件编译后的得到的Message.java测试代码测试结果

Protobuf 简介

  • 轻便高效的结构化数据存储格式
  • 更小、更快、更简洁
  • C++、Java、Python 三种语言的 API

Protobuf 下载

https://github.com/protocolbuffers/protobuf/releases/tag/v3.6.1

Protobuf 安装

代码语言:javascript
复制
tar -xzf protobuf-2.1.0.tar.gz 

cd protobuf

./configure

make 

make check 

make install

编写message.proto文件

代码语言:javascript
复制
syntax = "proto3";

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

    repeated Phone phone = 4;

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

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

编译message.proto文件

protobuf安装完毕后,根目录会出现protoc文件

代码语言:javascript
复制
protoc --java_out=./data ./data/message.proto

-I 后面是proto文件所在的目录 
–java_out 后面是生成java文件存放地址 
最后一个参数是proto文件的名称

编译后的得到的Message.java

代码语言:javascript
复制
public final class Message {
  private Message() {}
  public static void registerAllExtensions(
      com.google.protobuf.ExtensionRegistryLite registry) {
  }

  public static void registerAllExtensions(
      com.google.protobuf.ExtensionRegistry registry) {
    registerAllExtensions(
        (com.google.protobuf.ExtensionRegistryLite) registry);
  }
  public interface PersonOrBuilder extends
      // @@protoc_insertion_point(interface_extends:Person)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>int32 id = 1;</code>
     */
    int getId();

    /**
     * <code>string name = 2;</code>
     */
    String getName();
    /**
     * <code>string name = 2;</code>
     */
    com.google.protobuf.ByteString
        getNameBytes();

    /**
     * <code>repeated .Person.Phone phone = 4;</code>
     */
    java.util.List<Person.Phone>
        getPhoneList();
    /**
     * <code>repeated .Person.Phone phone = 4;</code>
     */
    Person.Phone getPhone(int index);
    /**
     * <code>repeated .Person.Phone phone = 4;</code>
     */
    int getPhoneCount();
    /**
     * <code>repeated .Person.Phone phone = 4;</code>
     */
    java.util.List<? extends Person.PhoneOrBuilder>
        getPhoneOrBuilderList();
    /**
     * <code>repeated .Person.Phone phone = 4;</code>
     */
    Person.PhoneOrBuilder getPhoneOrBuilder(
            int index);
  }
  /**
   * Protobuf type {@code Person}
   */
  public  static final class Person extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:Person)
      PersonOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use Person.newBuilder() to construct.
    private Person(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private Person() {
      id_ = 0;
      name_ = "";
      phone_ = java.util.Collections.emptyList();
    }

    @Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    private Person(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      this();
      if (extensionRegistry == null) {
        throw new NullPointerException();
      }
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            case 8: {

              id_ = input.readInt32();
              break;
            }
            case 18: {
              String s = input.readStringRequireUtf8();

              name_ = s;
              break;
            }
            case 34: {
              if (!((mutable_bitField0_ & 0x00000004) == 0x00000004)) {
                phone_ = new java.util.ArrayList<Phone>();
                mutable_bitField0_ |= 0x00000004;
              }
              phone_.add(
                  input.readMessage(Phone.parser(), extensionRegistry));
              break;
            }
            default: {
              if (!parseUnknownFieldProto3(
                  input, unknownFields, extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e).setUnfinishedMessage(this);
      } finally {
        if (((mutable_bitField0_ & 0x00000004) == 0x00000004)) {
          phone_ = java.util.Collections.unmodifiableList(phone_);
        }
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return Message.internal_static_Person_descriptor;
    }

    @Override
    protected FieldAccessorTable
        internalGetFieldAccessorTable() {
      return Message.internal_static_Person_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              Person.class, Builder.class);
    }

    /**
     * Protobuf enum {@code Person.PhoneType}
     */
    public enum PhoneType
        implements com.google.protobuf.ProtocolMessageEnum {
      /**
       * <code>MOBILE = 0;</code>
       */
      MOBILE(0),
      /**
       * <code>HOME = 1;</code>
       */
      HOME(1),
      /**
       * <code>WORK = 2;</code>
       */
      WORK(2),
      UNRECOGNIZED(-1),
      ;

      /**
       * <code>MOBILE = 0;</code>
       */
      public static final int MOBILE_VALUE = 0;
      /**
       * <code>HOME = 1;</code>
       */
      public static final int HOME_VALUE = 1;
      /**
       * <code>WORK = 2;</code>
       */
      public static final int WORK_VALUE = 2;


      public final int getNumber() {
        if (this == UNRECOGNIZED) {
          throw new IllegalArgumentException(
              "Can't get the number of an unknown enum value.");
        }
        return value;
      }

      /**
       * @deprecated Use {@link #forNumber(int)} instead.
       */
      @Deprecated
      public static PhoneType valueOf(int value) {
        return forNumber(value);
      }

      public static PhoneType forNumber(int value) {
        switch (value) {
          case 0: return MOBILE;
          case 1: return HOME;
          case 2: return WORK;
          default: return null;
        }
      }

      public static com.google.protobuf.Internal.EnumLiteMap<PhoneType>
          internalGetValueMap() {
        return internalValueMap;
      }
      private static final com.google.protobuf.Internal.EnumLiteMap<
          PhoneType> internalValueMap =
            new com.google.protobuf.Internal.EnumLiteMap<PhoneType>() {
              public PhoneType findValueByNumber(int number) {
                return PhoneType.forNumber(number);
              }
            };

      public final com.google.protobuf.Descriptors.EnumValueDescriptor
          getValueDescriptor() {
        return getDescriptor().getValues().get(ordinal());
      }
      public final com.google.protobuf.Descriptors.EnumDescriptor
          getDescriptorForType() {
        return getDescriptor();
      }
      public static final com.google.protobuf.Descriptors.EnumDescriptor
          getDescriptor() {
        return Person.getDescriptor().getEnumTypes().get(0);
      }

      private static final PhoneType[] VALUES = values();

      public static PhoneType valueOf(
          com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
        if (desc.getType() != getDescriptor()) {
          throw new IllegalArgumentException(
            "EnumValueDescriptor is not for this type.");
        }
        if (desc.getIndex() == -1) {
          return UNRECOGNIZED;
        }
        return VALUES[desc.getIndex()];
      }

      private final int value;

      private PhoneType(int value) {
        this.value = value;
      }

      // @@protoc_insertion_point(enum_scope:Person.PhoneType)
    }

    public interface PhoneOrBuilder extends
        // @@protoc_insertion_point(interface_extends:Person.Phone)
        com.google.protobuf.MessageOrBuilder {

      /**
       * <code>string number = 1;</code>
       */
      String getNumber();
      /**
       * <code>string number = 1;</code>
       */
      com.google.protobuf.ByteString
          getNumberBytes();

      /**
       * <code>.Person.PhoneType type = 2;</code>
       */
      int getTypeValue();
      /**
       * <code>.Person.PhoneType type = 2;</code>
       */
      PhoneType getType();
    }
    /**
     * Protobuf type {@code Person.Phone}
     */
    public  static final class Phone extends
        com.google.protobuf.GeneratedMessageV3 implements
        // @@protoc_insertion_point(message_implements:Person.Phone)
        PhoneOrBuilder {
    private static final long serialVersionUID = 0L;
      // Use Phone.newBuilder() to construct.
      private Phone(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
        super(builder);
      }
      private Phone() {
        number_ = "";
        type_ = 0;
      }

      @Override
      public final com.google.protobuf.UnknownFieldSet
      getUnknownFields() {
        return this.unknownFields;
      }
      private Phone(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        this();
        if (extensionRegistry == null) {
          throw new NullPointerException();
        }
        int mutable_bitField0_ = 0;
        com.google.protobuf.UnknownFieldSet.Builder unknownFields =
            com.google.protobuf.UnknownFieldSet.newBuilder();
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 10: {
                String s = input.readStringRequireUtf8();

                number_ = s;
                break;
              }
              case 16: {
                int rawValue = input.readEnum();

                type_ = rawValue;
                break;
              }
              default: {
                if (!parseUnknownFieldProto3(
                    input, unknownFields, extensionRegistry, tag)) {
                  done = true;
                }
                break;
              }
            }
          }
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(this);
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(
              e).setUnfinishedMessage(this);
        } finally {
          this.unknownFields = unknownFields.build();
          makeExtensionsImmutable();
        }
      }
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return Message.internal_static_Person_Phone_descriptor;
      }

      @Override
      protected FieldAccessorTable
          internalGetFieldAccessorTable() {
        return Message.internal_static_Person_Phone_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                Phone.class, Builder.class);
      }

      public static final int NUMBER_FIELD_NUMBER = 1;
      private volatile Object number_;
      /**
       * <code>string number = 1;</code>
       */
      public String getNumber() {
        Object ref = number_;
        if (ref instanceof String) {
          return (String) ref;
        } else {
          com.google.protobuf.ByteString bs = 
              (com.google.protobuf.ByteString) ref;
          String s = bs.toStringUtf8();
          number_ = s;
          return s;
        }
      }
      /**
       * <code>string number = 1;</code>
       */
      public com.google.protobuf.ByteString
          getNumberBytes() {
        Object ref = number_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (String) ref);
          number_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }

      public static final int TYPE_FIELD_NUMBER = 2;
      private int type_;
      /**
       * <code>.Person.PhoneType type = 2;</code>
       */
      public int getTypeValue() {
        return type_;
      }
      /**
       * <code>.Person.PhoneType type = 2;</code>
       */
      public PhoneType getType() {
        @SuppressWarnings("deprecation")
        PhoneType result = PhoneType.valueOf(type_);
        return result == null ? PhoneType.UNRECOGNIZED : result;
      }

      private byte memoizedIsInitialized = -1;
      @Override
      public final boolean isInitialized() {
        byte isInitialized = memoizedIsInitialized;
        if (isInitialized == 1) return true;
        if (isInitialized == 0) return false;

        memoizedIsInitialized = 1;
        return true;
      }

      @Override
      public void writeTo(com.google.protobuf.CodedOutputStream output)
                          throws java.io.IOException {
        if (!getNumberBytes().isEmpty()) {
          com.google.protobuf.GeneratedMessageV3.writeString(output, 1, number_);
        }
        if (type_ != PhoneType.MOBILE.getNumber()) {
          output.writeEnum(2, type_);
        }
        unknownFields.writeTo(output);
      }

      @Override
      public int getSerializedSize() {
        int size = memoizedSize;
        if (size != -1) return size;

        size = 0;
        if (!getNumberBytes().isEmpty()) {
          size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, number_);
        }
        if (type_ != PhoneType.MOBILE.getNumber()) {
          size += com.google.protobuf.CodedOutputStream
            .computeEnumSize(2, type_);
        }
        size += unknownFields.getSerializedSize();
        memoizedSize = size;
        return size;
      }

      @Override
      public boolean equals(final Object obj) {
        if (obj == this) {
         return true;
        }
        if (!(obj instanceof Phone)) {
          return super.equals(obj);
        }
        Phone other = (Phone) obj;

        boolean result = true;
        result = result && getNumber()
            .equals(other.getNumber());
        result = result && type_ == other.type_;
        result = result && unknownFields.equals(other.unknownFields);
        return result;
      }

     ······此处省去N行代码······

   

  // @@protoc_insertion_point(outer_class_scope)
}

测试代码

代码语言:javascript
复制
public class Main {
    public static void main(String[] args) {
        Message.Person.Builder personBuilder = Message.Person.newBuilder();
        personBuilder.setId(12345678);
        personBuilder.setName("Admin");
        personBuilder.addPhone(Message.Person.Phone.newBuilder().setNumber("10010").setType(Message.Person.PhoneType.MOBILE));
        personBuilder.addPhone(Message.Person.Phone.newBuilder().setNumber("10086").setType(Message.Person.PhoneType.HOME));
        personBuilder.addPhone(Message.Person.Phone.newBuilder().setNumber("10000").setType(Message.Person.PhoneType.WORK));

        Message.Person person = personBuilder.build();
        byte[] buff = person.toByteArray();

        try {
            Message.Person personOut = Message.Person.parseFrom(buff);
            System.out.printf("Id:%d, Name:%s\n", personOut.getId(), personOut.getName());

            List<Message.Person.Phone> phoneList = personOut.getPhoneList();

            for (Message.Person.Phone phone : phoneList) {
                System.out.printf("PhoneNumber:%s (%s)\n", phone.getNumber(), phone.getType());
            }

        } catch (InvalidProtocolBufferException e) {
            e.printStackTrace();
        }
        //Person类的字节码
        System.out.println(Arrays.toString(buff));

    }
}

测试结果

代码语言:javascript
复制
Id:12345678, Name:Admin
PhoneNumber:10010 (MOBILE)
PhoneNumber:10086 (HOME)
PhoneNumber:10000 (WORK)
[8, -50, -62, -15, 5, 18, 5, 65, 100, 109, 105, 110, 34, 7, 10, 5, 49, 48, 48, 49, 48, 34, 9, 10, 5, 49, 48, 48, 56, 54, 16, 1, 34, 9, 10, 5, 49, 48, 48, 48, 48, 16, 2]
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-09-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 落叶飞翔的蜗牛 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 内容目录
  • Protobuf 简介
  • Protobuf 下载
  • Protobuf 安装
  • 编写message.proto文件
  • 编译message.proto文件
  • 编译后的得到的Message.java
  • 测试代码
  • 测试结果
相关产品与服务
数据保险箱
数据保险箱(Cloud Data Coffer Service,CDCS)为您提供更高安全系数的企业核心数据存储服务。您可以通过自定义过期天数的方法删除数据,避免误删带来的损害,还可以将数据跨地域存储,防止一些不可抗因素导致的数据丢失。数据保险箱支持通过控制台、API 等多样化方式快速简单接入,实现海量数据的存储管理。您可以使用数据保险箱对文件数据进行上传、下载,最终实现数据的安全存储和提取。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档