protobuf是google开源的一个序列化方案,根据google的benchmarking测试,各个方面的表现都非常不错。详细的可以参考下面的基准测试项目:https://github.com/eishay/jvm-serializers/wiki
protobuf的使用很简单,但是,google被墙了,造成下载和搭建环境比较麻烦。我这里就来一个完整的处理过程,搭建按照这个步骤就能够简单的体验protobuf了。我本机的环境是Ubuntu 14。可以参考。
下载源码
首先,从github上下载protobuf的源码,github的地址:https://github.com/google/protobuf
shell>Git clone https://github.com/google/protobuf.git
编译异常处理
现在,我们基本上可以按照github上的编译步骤进行操作,但是,有两点需要注意
1.我们现在是使用的源码构建,必须切换到合适的release版本。
git tag
git checkout v2.6.1
2.你会发现按照github上面编译,第一步就报错。
查看脚本的内容,它去下载一个google的gtest的东西,因为“众所周知”的原因,下载失败,造成不能生成configure文件。这个时候,可以手动去网络上下载这个zip包,解压,并且重命名为gtest。就可以继续编译了。
我的资源中上传了一个,大家也可以自行下载。
Linux公社资源站下载:
------------------------------------------分割线------------------------------------------
具体下载目录在 /2017年资料/3月/27日/Ubuntu 14.04下ProtoBuf环境搭建及序列化示例/
------------------------------------------分割线------------------------------------------
下面给出操作步骤
unzip gtest-1.7.0.zip
mv gtest-1.7.0 gtest
./autogen.sh
编译安装
经过上面的操作就能生成configure文件了。就可以按照github上面的步骤正常编译了
./configure --prefix=/usr
make
make check
make install
这个时候编译安装就已经完成了。
序列化demo
搭建一个maven项目
只需要一个简单的maven项目就行了,可以直接跳过archtype的选择。
在pom.xml中添加如下依赖
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>2.6.1</version>
</dependency>
写一个schema文件,放置到包目录就可以。就是官方网站上的简单示例。
syntax="proto2";
package tutorial;
option java_package = "com.wu.protobuf";
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 phone = 4;
}
message AddressBook {
repeated Person person = 1;
}
然后,就可以使用protobuf的编译器,生成对应的stub了。切换到项目的src/main/java目录
protoc --java_out=. com/wu/addressbook.proto
eclipse中刷新项目源码目录就可以看到生成的文件了。
然后编写一个类进行测试。
package com.wu.protobuf;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import com.wu.protobuf.AddressBookProtos.AddressBook;
import com.wu.protobuf.AddressBookProtos.Person;
public class ProtocDemo {
public static void Print(AddressBook addressBook) {
for (Person person: addressBook.getPersonList()) {
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.getPhoneList()) {
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());
}
}
}
public void serialize() throws IOException{
//build message
Person john =
Person.newBuilder()
.setId(1234)
.setName("John Doe")
.setEmail("jdoe@example.com")
.addPhone(
Person.PhoneNumber.newBuilder()
.setNumber("555-4321")
.setType(Person.PhoneType.HOME))
.build();
AddressBook.Builder addressBook = AddressBook.newBuilder();
addressBook.addPerson(john);
//serialize to disk
FileOutputStream output = new FileOutputStream("addressbook.pbd");
addressBook.build().writeTo(output);
output.close();
}
public void deserialize() throws FileNotFoundException, IOException{
AddressBook addressBook =
AddressBook.parseFrom(new FileInputStream("addressbook.pbd"));