Google Protocol Buffers (ProtoBuf)是Google开源的数据序列化工具/框架/方法,比使用XML更小、更快、也更简单高效。目前Hadoop, HBase等很多开源软件使用ProtoBuf作为序列化工具。官方网站: https://developers.google.com/protocol-buffers/
在Windows上搭建Protobuf Java实验环境需要如下软件:
1. MS Visual Studio C++ (编译protoc, optional)
2. JDK (编译Java源码)
3. Maven (build protobuf jar包)
第一步:下载源码及Windows下编译好的protoc.exe, 下载地址:https://developers.google.com/protocol-buffers/docs/downloads
如果你的Windows上安装了Visual Studio,就可以不用下载protoc.exe,可以用源码编译出protoc。博主的电脑上没有Visual Studio, 因此直接下载了protoc.exe
第二步:下载及安装Maven, Maven官网:http://maven.apache.org/
安装后将maven的bin目录设置到Window path环境变量下
第三步:编译protobuf jar包
将下载的protoc.exe放到src目录,然后进入java目录运行:
mvn package
在target目录下产生protobuf-java-2.6.0.jar
mvn install
将jar包安装到maven repository.
至此我们得到了开发protobuf Java应用需要的protoc.exe和protobuf-java-2.6.0.jar, 这是我们开发protobuf Java应用仅需要的2个文件。下面就可以开发应用了。
Protobuf Java应用开发
1. 创建项目
mvn archetype:generate -DgroupId=proto -DartifactId=ProtobufTest
并生成eclipse项目:
mvn eclipse:eclipse
然后用eclipse打开项目, 进入Eclipse, Import -> Existing Maven Projects
2. 创建proto文件
在proto包中创建文件addressbook.proto,内容如下:
package proto.generated;
option java_package = "proto.generated";
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;
}
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>2.6.0</version>
</dependency>
package proto;
import proto.generated.AddressBookProtos.AddressBook;
import proto.generated.AddressBookProtos.Person;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
class AddPerson {
static Person newPerson() {
Person.Builder person = Person.newBuilder();
person.setId(1);
person.setName("Mike");
person.setEmail("mike@abc.com");
Person.PhoneNumber.Builder phoneNumber =
Person.PhoneNumber.newBuilder().setNumber("12388888888");
phoneNumber.setType(Person.PhoneType.MOBILE);
person.addPhone(phoneNumber);
return person.build();
}
public static void main(String[] args) throws Exception {
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(AddPerson.newPerson());
// Write the new address book back to disk.
FileOutputStream output = new FileOutputStream(args[0]);
addressBook.build().writeTo(output);
output.close();
}
}
package proto;
import proto.generated.AddressBookProtos.AddressBook;
import proto.generated.AddressBookProtos.Person;
import java.io.FileInputStream;
class ListPeople {
// Iterates though all people in the AddressBook and prints info about them.
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());
}
}
}
// 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);
}
}