protocol buffers 是一种语言无关、平台无关、可扩展的序列化结构数据的方法,它可用于(数据)通信协议、数据存储等。
1.序列化后体积相比Json和XML很小,适合网络传输
2.支持跨平台多语言
3.消息格式升级和兼容性还不错
4.序列化反序列化速度很快,快于Json的处理速度快
1.语言无关、平台无关。即 ProtoBuf 支持 Java、C++、Python 等多种
语言,支持多个平台
2.高效。
3.扩展性、兼容性好。你可以更新数据结构,而不影响和破坏原有的旧程
序
使用 proto语法编写的文本文件, 用来定义数据格式。
当你使用protobuf编译器编译一个.proto文件,它会生成在.proto内你描述的消息类型的操作代码,这些代码是根据你所选择的编程功能语言决定的。这些操作代码内包含了设置字段值和读取字段值,以及序列化到输出流和从输入流反序列化。
addressbook.proto
// See README.txt for information and build instructions.
//
// Note: START and END tags are used in comments to define sections used in
// tutorials. They are not part of the syntax for Protocol Buffers.
//
// To get an in-depth walkthrough of this file and the related examples, see:
// https://developers.google.com/protocol-buffers/docs/tutorials
// [START declaration]
syntax = "proto3";
package tutorial;
import "google/protobuf/timestamp.proto";
// [END declaration]
// [START java_declaration]
option java_package = "com.example.tutorial";
option java_outer_classname = "AddressBookProtos";
// [END java_declaration]
// [START csharp_declaration]
option csharp_namespace = "Google.Protobuf.Examples.AddressBook";
// [END csharp_declaration]
// [START messages]
message Person {
string name = 1;
int32 id = 2; // Unique ID number for this person.
string email = 3;
enum PhoneType {
MOBILE = 0;
HOME = 1;
WORK = 2;
}
message PhoneNumber {
string number = 1;
PhoneType type = 2;
}
repeated PhoneNumber phones = 4;
google.protobuf.Timestamp last_updated = 5;
}
// Our address book file is just one of these.
message AddressBook {
repeated Person people = 1;
}
// [END messages]
将 proto 文件编译成不同语言的实现, 这样不同语言中的数据就可以用 protobuf 格式的数据进行交互。
C++:编译器会按照每个.proto文件生成与其对应的.h和.cc文件,每个消息类似 都有独立的消息操作类。
Java:编译器将会生成一个.java文件和一个操作类,此操作类为所有消息类型所共有, 使用一个特别的Builder类为每个消息类型实例化。
Python:有一点不同 – 编译器会为每个消息生成一个模块每个模块有一个静态描述符, 该模块与一个元类在运行时创建一个所需数据操作类。
protoc.exe --java_out=./ addressbook.proto
生成AddressBookProtos.java文件和对应的目录结构:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
protobuf 运行时所需要的库,包括生成代码中依赖的库和操作生成代码的库。
<dependency>
<groupId>com.google.protobufgroupId>
<artifactId>protobuf-javaartifactId>
<version>3.11.0version>
dependency>
<dependency>
<groupId>com.google.protobufgroupId>
<artifactId>protobuf-java-utilartifactId>
<version>3.11.0version>
dependency>
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.addPhones(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 {
String addressBookPath="./address_book";
AddressBook.Builder addressBook = AddressBook.newBuilder();
// Read the existing address book.
try {
FileInputStream input = new FileInputStream(addressBookPath);
try {
addressBook.mergeFrom(input);
System.out.println(addressBook.toString());
} finally {
try { input.close(); } catch (Throwable ignore) {}
}
} catch (FileNotFoundException e) {
System.out.println(args[0] + ": File not found. Creating a new file.");
}
/* // Add an address.
addressBook.addPeople(
PromptForAddress(new BufferedReader(new InputStreamReader(System.in)),
System.out));
// Write the new address book back to disk.
FileOutputStream output = new FileOutputStream(addressBookPath);
try {
addressBook.build().writeTo(output);
} finally {
output.close();
}*/
}
}