Protocol Buffers(簡稱protobuf)是谷歌的一項技術。用于将結構化的資料序列化、反序列化。經經常使用于網絡傳輸。
這貨實際上相似于XML生成和解析。但protobuf的效率高于XML,隻是protobuf生成的是位元組碼,可讀性比XML差。相似的還有json、Java的Serializable等。
protobuf支援各種語言。本文以Java為例。簡介protobuf怎樣使用。
其它語言用法相似。
首先須要下載下傳:
解壓後有兩個檔案:protobuf-java-2.5.0.jar和protoc.exe。
protobuf-java-2.5.0.jar即protobuf所須要的jar包。假設用maven的話能夠無視這個檔案;
protoc.exe是protobuf代碼生成工具。
第一步:定義資料結構
首先要定義protobuf的資料結構,這裡要寫一個.proto檔案。這個檔案有點相似于定義一個類。
比如定義一個Person。儲存檔案PersonMsg.proto(注意檔案名稱和裡面的message名不要一樣)。
message Person {
// ID(必需)
required int32 id = 1;
// 姓名(必需)
required string name = 2;
// email(可選)
optional string email = 3;
// 朋友(集合)
repeated string friends = 4;
}
上面的1、2、3、4是unique numbered tag,是一個唯一辨別。
上面的樣例中定義了一個很easy的資料結構,當然還能夠定義更複雜的結構,這裡不再讨論,詳細能夠看官方文檔。
第二步:protoc.exe生成Java代碼
使用檔案protoc.exe,cmd指令行執行:
protoc.exe --java_out=E:\java PersonMsg.proto
輸入檔案是PersonMsg.proto。也就是定義資料結構的檔案;輸出目錄是E:\java,将java檔案生成在E:\java中。執行指令成功後會生成PersonMsg.java:
在Eclipse中建立一個項目,将java檔案複制到項目中。項目中須要引入protobuf-java-2.5.0.jar包。
假設是maven項目則增加:
com.google.protobuf
protobuf-java
2.5.0
第三步:序列化
第四步:反序列化
一般來說。序列化和反序列化是分開的。比如網絡傳輸,由一方将資料序列化後發送給還有一方來接收并解析。序列化發送和接收反序列化并不在一起。可是以下為了樣例簡單将二者寫在同一程式中。
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.List;
public class Main {
public static void main(String[] args) throws IOException {
// 依照定義的資料結構,建立一個Person
PersonMsg.Person.Builder personBuilder = PersonMsg.Person.newBuilder();
personBuilder.setId(1);
personBuilder.setName("叉叉哥");
personBuilder.setEmail("[email protected]");
personBuilder.addFriends("Friend A");
personBuilder.addFriends("Friend B");
PersonMsg.Person xxg = personBuilder.build();
// 将資料寫到輸出流,如網絡輸出流,這裡就用ByteArrayOutputStream來取代
ByteArrayOutputStream output = new ByteArrayOutputStream();
xxg.writeTo(output);
// -------------- 切割線:上面是發送方,将資料序列化後發送 ---------------
byte[] byteArray = output.toByteArray();
// -------------- 切割線:以下是接收方,将資料接收後反序列化 ---------------
// 接收到流并讀取,如網絡輸入流,這裡用ByteArrayInputStream來取代
ByteArrayInputStream input = new ByteArrayInputStream(byteArray);
// 反序列化
PersonMsg.Person xxg2 = PersonMsg.Person.parseFrom(input);
System.out.println("ID:" + xxg2.getId());
System.out.println("name:" + xxg2.getName());
System.out.println("email:" + xxg2.getEmail());
System.out.println("friend:");
List friends = xxg2.getFriendsList();
for(String friend : friends) {
System.out.println(friend);
}
}
}