Google ProtoBuf快速入门

来源:互联网 发布:mysql如何修改密码 编辑:程序博客网 时间:2024/05/31 06:21

Protobuf是一个灵活的、高效的用于序列化数据的协议。相比较XML和JSON格式,protobuf更小、更快、更便捷。google protobuf是跨语言的,并且自带了一个编译器(protoc),只需要用它进行编译,可以编译成Java、python、C++、C#、Go等代码,然后就可以直接使用,不需要再写其他代码,自带有解析的代码。本篇文章将简要的介绍Java程序员如何使用Protobuf。

安装Protobuf编译器

工欲善其事,必先利其器。在使用Protobuf进行开发前,需要安装Protobuf的编译器。Protobuf编译器能够将.proto描述文件解析为特定特定语言中的类。我们可以通过两种途径获取代码,一种是通过google protobuf github,另一种比较简单的做法是从Protobuf的发行版页面中下载合适版本的预构建文件,这里我们下载protobuf-java-3.3.0.tar.gz

下载完成后,进行解压安装

tar -zxvf protobuf-java-3.3.0.tar.gzcd protobuf-java-3.3.0./configure #进行环境监测,并生成makefile文件make # 编译make install # 安装

这里有两点需要注意:
1. 如果是通过github下载源码编译安装,则需要先执行./autogen.sh,这一步主要用来联网获取GoogleMock数据,并生成对应的configure脚本。脚本生成完成后,编译安装步骤和下载release包时一样;
2. 在./configure进行环境检测时,可以通过–prefix=/user/local来指定安装路径

安装完成后,可以通过–version命令来检测是否安装成功

$ protoc --versionlibprotoc 3.3.0

编写proto描述文件

我们以protobuf官网java入门教程中的例子为例,编写一个addressbook.proto

package tutorial;option java_package = "com.example.tutorial";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];    }    repeated PhoneNumber phones = 4;}message AddressBook{    repeated Person people = 1;}

需要进行说明的几点:
1. package声明是为了防止不同项目中的命名冲突。option java_package的意思是说,如果该.proto被编译为Java类型的文件,则包名使用java_package制定的路径,否则使用默认路径
2. option java_outer_classname用来声明包含.proto中所有类的类的名字,也即最外层类的名字。如果不指定的话,默认使用.proto文件名的驼峰形式。例如my_proto.proto编译生成的类文件名为MyProto
3. message用来代表一个类,required用来代表该字段是必须的,缺少该字段将会导致解析异常;option代表可选的,可有可无;repeated代表数组,意味着可以多次出现。

关于Protobuf语法的更多介绍,猛戳这里

编译Proto描述文件

使用前面安装好的protoc工具编译addressbook.proto,命令如下:

protoc -I=$SRC_DIR --java_out=$DST_DIR $SRC_DIR/addressbook.proto

SRC_DIR用来指定源码位置,如果不指定的话,默认为当前目录,DST_DIR用来制定输出目录,如果不指定的话,默认为当前位置,–java_out用来指定生成的为java类;如果要生成C++类,则通过–cpp_out来指定。

由于我的当前工作目录已经和addressbook.proto在同一级,因此我不需要指定SRC_DIR,运行命令:

protoc --java_out=./ ./addressbook.proto

如果运行一切顺利,会在当前目录中生成com.example.tutorial/AddressBookProtos.java,这个类中包含属性的getter和setter方法,用build模式进行构造。

使用生成的Java类

public static void main(String[] args) throws IOException {    Person john = Person.newBuilder()            .setId(1234)            .setName("Hone Doe")            .setEmail("jdoe@example.com")            .addPhones(Person.PhoneNumber.newBuilder()                    .setNumber("555-4321")                    .setType(Person.PhoneType.HOME)            ).build();    System.out.println(john.toString());    byte[] bytes = john.toByteArray();    for(int i = 0;i < bytes.length;i++){        System.out.print(Integer.toBinaryString(bytes[i]));    }    System.out.println("");    /**===============================================*/    Person person = Person.parseFrom(bytes);    System.out.println(person.toString());}

使用build模式构建对象以后,进行序列化和反序列化的工作就变的很简单了,我们可以通过调用toByteArray方法,将对象转换为字节数组;可以通过parseFrom方法,将字节数组转换为Java对象。

这里只是一个简单的介绍,更多Protobuf对象的方法,请戳这里

1 0
原创粉丝点击