由于项目的关系,前不久学习了Protocol Buffer。刚开始的时候,有些迷茫,网上的资料大多是介绍C++语言环境下的,或者是不太完整的java环境的介绍。后来只好去官网看官方的文档,通过文档一步一步学习,终于有了一些进展。为使初学者少走弯路,特此分享自己的经历。
Ps:为准确理解资料的含义,建议阅读官方文档。好了,进入主题吧!
protobuf介绍
按照官网的描述:protobuf是google提供的一个开源序列化框架。主要应用于通信协议,数据存储中的结构化数据的序列化。它类似于XML,JSON这样的数据表示语言,其最大的特点是基于二进制,因此比传统的XML表示高效短小得多。虽然是二进制数据格式,但并没有因此变得复杂,开发人员通过按照一定的语法定义结构化的消息格式,然后送给命令行工具,工具将自动生成相关的类,可以支持java、c++、python等语言环境。通过将这些类包含在项目中,可以很轻松的调用相关方法来完成业务消息的序列化与反序列化工作。
protobuf的优势
1、语言中立
2、平台中立
3、高效性
protobuf入门(eclipse下java环境的搭建)
更多案例请查阅源代码包protobuf-2.3.0.zip 里面有关于各种支持语言(java,C++,python等)的案例。
1、下载jar包 protobuf-java-2.3.0.jar
2、下载编译器protoc.exe
3、新建java工程test_protobuf
4、导入protobuf-java-2.3.0.jar包
5、导入编译器protoc.exe到项目下
6、在项目下建存放文件.proto的文件夹proto
7、编写message并放在proto文件夹下,有关编写规范和说明请参考官网文档,在这里我引用官网的例子,创建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; // Unique ID number for this person.
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;
}
// Our address book file is just one of these.
message AddressBook {
repeated Person person = 1;
}
8、编译addressbook.proto成指定的java类
命令行下进入编译器所在目录,执行如下命令
protoc -I=proto/ --java_out=src proto/addressbook.proto
其中,src为生成的java类的目标位置,这里我们选择项目的默认包,proto/addressbook.proto表示我们的proto文件,运行后即生成java类,生成的java类被放在了package com.example.tutorial中。刚才我们指定的目标位置是src,为什么现在却被放在了这个包中呢?这和我们的addressbook.proto文件中的option java_package = "com.example.tutorial";有关。欲了解更多,参考上节提到的官方文档。
9、现在有了生成的AddressBookProtos.java类,我们可以向文件里写入消息了,首先编写AddPerson.java,代码如下:
import com.example.tutorial.AddressBookProtos.AddressBook;
import com.example.tutorial.AddressBookProtos.Person;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.IOException;
import java.io.PrintStream;
class AddPerson{
// This function fills in a Person message based on user input.
static Person PromptForAddress(BufferedReader stdin,PrintStream stdout)throws IOException{
Person.Builder person = Person.newBuilder();
stdout.print("Enter person ID: ");
person.setId(Integer.valueOf(stdin.readLine()));
stdout.print("Enter name: ");
person.setName(stdin.readLine());
stdout.print("Enter email address (blank for none): ");
String email = stdin.readLine();
if (email.length() > 0){
person.setEmail(email);
}
while (true){
stdout.print("Enter a phone number (or leave blank to finish): ");
String number = stdin.readLine();
if (number.length() == 0){
break;
}
Person.PhoneNumber.Builder phoneNumber = Person.PhoneNumber.newBuilder().setNumber(number);
stdout.print("Is this a mobile, home, or work phone? ");
String type = stdin.readLine();
if (type.equals("mobile")){
phoneNumber.setType(Person.PhoneType.MOBILE);
} else if (type.equals("home")) {
phoneNumber.setType(Person.PhoneType.HOME);
} else if (type.equals("work")) {
phoneNumber.setType(Person.PhoneType.WORK);
} else {
stdout.println("Unknown phone type. Using default.");
}
person.addPhone(phoneNumber);
}
return person.build();
}
// Main function: Reads the entire address book from a file, adds one person based on user input,
//then writes it back out to the same file.
public static void main(String[] args) throws Exception{
if (args.length != 1) {
System.err.println("Usage: AddPerson ADDRESS_BOOK_FILE");
System.exit(-1);
}
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(
PromptForAddress(new BufferedReader(new InputStreamReader(System.in)), System.out));
// Write the new address book back to disk.
FileOutputStream output = new FileOutputStream(args[0]);
addressBook.build().writeTo(output);
output.close();
}
}
首先配置参数,也就是消息被序列化后存储的文件名,这里,我们就把参数设置成AddressBook.代码中提到,运行时如果文件不存在,将会创建文件并写入;如果存在,就写入。运行程序,按照提示输入消息。然后查看我们的项目路径下,将会产生AddressBook文件
10、上一步是将消息序列化到文件中,这一步将文件中的消息反序列化,类似地,我们创建一个类:ListPeople.java 代码如下:
import com.example.tutorial.AddressBookProtos.AddressBook;
import com.example.tutorial.AddressBookProtos.Person;
import java.io.FileInputStream;
public 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.
/**
* @param args
* @throws Exception
*/
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);
}
}
运行程序,将会看到我们输入的消息体被遍历并打印出来了!
通过一个简单的例子,希望能够对大家有所帮助!!
分享到:
相关推荐
Google Protocol Buffer 详细入门Google Protocol Buffer 详细入门
Protocol Buffer 中存在一张类型对照表,用于将 Protocol Buffer 中的数据类型与其他编程语言(C++/Java)中的类型进行对照。该对照表将在后面给出。 Protocol Buffer 的优点 1. 保持良好的风格和系统性 2. 结合...
标题中的"Protocol Buffer java版本"指的是Protocol Buffer支持Java语言的实现。 在Java中,Protocol Buffer提供了SDK,允许开发者定义数据结构(称为.proto文件),然后生成对应的Java类,这些类可以用来序列化和...
ProtocolBuffer,简称PB,是由Google开发的一种数据序列化协议,它是Google的一种二进制数据交换格式,用于结构化数据的序列化。Protocol Buffers的设计目标是替代XML等传统数据交换格式,提供更高效、更小的数据...
Protocol Buffer(简称protobuf)是Google开发的一种数据序列化协议,它是跨平台、语言无关的,用于结构化数据的高效序列化方法。protobuf提供了一种方式将数据结构定义为.proto文件,然后可以使用protobuf编译器...
- Protocol Buffer:PB的设计目标之一就是跨语言兼容,它支持多种编程语言,包括C++、Java、Python等,方便多语言环境下的数据交换。 - Java序列化:主要针对Java平台,跨语言支持较差,若要在非Java环境中使用,...
2. **Java库**:编译后的Java代码依赖于Protocol Buffer的Java库,它提供了序列化和反序列化的API。这个库包含了`com.google.protobuf`包,其中包含`Message`接口和`Builder`类等核心组件,用于创建和操作Protocol ...
2. **编译器**:`protoc`是Protocol Buffer提供的编译器,它可以将.proto文件编译成不同编程语言(如C++、Java、Python等)的源代码,生成的类库提供了序列化和反序列化的接口。 3. **序列化与反序列化**:Protocol...
描述中提到"已经编译好的cocos2d-x的protocol buffer库",这通常包括了Protocol Buffer的动态或静态库文件,这些库文件是预先通过编译Protocol Buffer的源代码生成的,适用于Cocos2d-x的环境。这些库文件允许Cocos2d...
- **Protocol Buffer**是一种用于数据序列化的高效工具,支持多种编程语言(如Java、C++、Python等),能够实现数据的有效存储和传输。 #### 二、概念与工作原理 1. **概念介绍** - **Protocol Buffer**:一种...
4. **跨平台和跨语言兼容性**: Protocol Buffer 3.0 改进了跨平台和跨语言的兼容性,不仅支持C++,还支持Java、Python等多种编程语言。这意味着定义的数据结构可以在不同语言的系统之间无缝共享。 5. **性能优化**:...
通过这个插件,Protocol Buffer开发者可以在Sublime Text 3环境中获得更专业的开发体验,提高代码质量和效率。同时,熟悉和掌握Protocol Buffer的语法和应用,对于进行跨平台、高性能的数据交换具有重要意义。
为了减小通信开销和提高同步效率,使用Protocol Buffer的优势就显现出来了:它的数据压缩性好,传输速度快,且解析效率高,这些都是移动互联网环境下非常重要的特性。 Protocol Buffer的工作原理是,开发者首先定义...
Protocol Buffer(简称protobuf)是Google开发的一种数据序列化协议,用于高效、跨平台地存储和传输结构化数据。它能够将复杂的数据结构转换为二进制格式,以便在网络通信和文件存储中使用,大大减少了数据的存储...
Protocol Buffer 2.5.0 jar包
### Protocol Buffer 配置及实例详解 #### 一、Protocol Buffers 概述 Protocol Buffers 被定义为一种数据描述语言(Data Description Language,DDL),它在 Google 内部得到了广泛的应用,主要用于结构化数据的...
Protocol Buffer技术是Google开发的一种数据序列化协议,用于高效地编码和解码结构化数据。在C++中,Protocol Buffer提供了强大的工具`protoc`,用于将`.proto`文件转换为对应编程语言(如C++)的源代码,使得开发者...