Protocol Buffers 短暂介绍

protobuf简介

protocolbuffer(以下简称PB)是google 的一种数据交换的格式,它独立于语言,独立于平台。google 提供了多种语言的实现:java、c#、c++、go 和 python,每一种实现都包含了相应语言的编译器以及库文件。由于它是一种二进制的格式,比使用 xml 进行数据交换快许多。可以把它用于分布式应用之间的数据通信或者异构环境下的数据交换。作为一种效率和兼容性都很优秀的二进制数据传输格式,可以用于诸如网络传输、配置文件、数据存储等诸多领域。

protocol buffer初步使用

下面是一个简单的使用的例子:
首先需要定义一个.proto文件,其中需要定义你希望操作的对象的结构。

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];
  }
 
  repeated PhoneNumber phone = 4;
}

保存为person.proto文件,之后下载protoc编译工具,并解压,使用PB将proto文件生成java类。

protoc.exe --java_out=. person.proto

在指定的java_out目录下就可以生成java对应的类,这里生成了PersonOuterClass.java。将文件放入项目,并引入PB的jar包。

compile group: 'com.google.protobuf', name: 'protobuf-java', version: '3.1.0'

接下来就可以使用PB进行对象的操作了。

public static void main(String[] args) throws Exception{
        //创建对象
        PersonOuterClass.Person p= PersonOuterClass.Person.newBuilder().setName("my_name").setId(2).build();
        System.out.print(p.toString());
        //序列化对象
        FileOutputStream fos=new FileOutputStream("D://person");
        p.writeTo(fos);
        fos.close();
        //反序列化对象
        FileInputStream fis=new FileInputStream("D://person");
        PersonOuterClass.Person pread=PersonOuterClass.Person.parseFrom(fis);
        System.out.println(pread.toString());
        fis.close();
 }

与java原生的serializable接口进行比较

public class JavaPerson implements Serializable{
       public String name;
       public Integer id;
       public String email;
        
       public enum PhoneType{
           MOBILE,HOME,WORK
       }
       public class PhoneNumber{
           public String number;
           public PhoneType type;
       }
       List phone;
        
       public static void main(String[] args) throws Exception{
           JavaPerson jp=new JavaPerson();
           jp.name="my_name";
           jp.id=2;
 
           FileOutputStream fileOut = new FileOutputStream("d://person.ser");
           ObjectOutputStream outStream = new ObjectOutputStream(fileOut);
           outStream.writeObject(jp);
           outStream.close();
           fileOut.close();
 
 
           FileInputStream fileIn =new FileInputStream("d://person.ser");
           ObjectInputStream in = new ObjectInputStream(fileIn);
           jp = (JavaPerson) in.readObject();
           in.close();
           fileIn.close();
       }
   }

运行比较结果:

PB较java默认形式代码更简洁。
循环运行10000次序列化和反序列化后PB比java快约30%。
生成的文件PB有11字节而java有215字节。
PB提供额外的字段校验支持。