protobuf(Protocol Buffers)java初體驗


        因為項目須要所以簡單的研究了下protobuf。我也是參照網上的博客,所以大部分內容我也就不反復造輪子了。首先protobuf介紹點擊這里,使用介紹點擊這里,使用demo看這里

我個人的第一個樣例也是參照這個demo來的。只是當中我有遇到一些問題,所以揪出來說說,也就給自己做個筆記,方便查閱。

        主要的東西相信大家也了解了。直接步入主題了:

        1、限定修飾符介紹 required\optional\repeated,之前給定的博客已經有這個介紹了我也不多說。這里把一些小玩兒拿出來講講

       ①、required必須的字段,假設不賦值就會拋出 com.google.protobuf.UninitializedMessageException: Message missing required fields: ...異常

       ②、optional可選字段,沒什么好說的就是可有可無咯

       ③、repeated可反復的字段能夠用來表示數組,在這里我還小小的糾結了會,搞過去就好了(糾結了好一會才知道protobuf數組怎么定義)。事實上定義數組非常easyrepeated string name=字段號;然后在賦值的剛開始用數組的形式來賦值,會拋出java.lang.IndexOutOfBoundsException: Index: 0, Size: 0的異常,我在想size為0,也就是說不能這樣搞呀,然后看了下源代碼是com.google.protobuf.LazyStringList name_ = com.google.protobuf.LazyStringArrayList.EMPTY這種,也就是說這個玩兒就是個集合嘛。所以賦值就用集合那套來搞定好了

       2、接下來就是正式開始了,首先准備所以須要的protoc.exe和protobuf的jar包。下載點擊這里。沒什么好配置的。所以開始吧。

       ①、首先編寫一個proto文件,這里我的文件是test.proto

package protobuf; 
option java_package = "com.test.protobuf"; 
option java_outer_classname = "FirstProtobuf"; 
message testBuf  { 
  required int32 ID = 1; 
  optional string Url = 2; 
  repeated string name=3; 
  
   enum PhoneType { 
    MOBILE = 0; 
    HOME = 1; 
    WORK = 2; 
  }
}

定義包名什么的就沒什么好說的了。

option java_outer_classname = "FirstProtobuf";定義生成類的名字

message testBuf定義一個message內部類基本的字段什么就在這里面了

required int32 ID = 1; 定義字段,每一個字段都必須有一個唯一的字段號,由於我也是初體驗所以也不知道這個字段號究竟有什么用,可是不寫編譯就會出Missing field number的錯,反復就會出Field number 1 has already been used in "protobuf.testBuf" by field "....".的錯

       ②、將文件放在解壓的protoc.exe同級文件夾下

       ③、就該編譯了,我這里依照網上說的(protoc.exe --java_out=./test.proto)編譯出現了問題Missing input file.然后查了下問題解決,查看原文,所以用protoc ./test.proto --java_out=./命令編譯通過

       ④、把生成的文件拷到新建的java文件夾下,然后把jar拷貝進來build path下

       ⑤、開始測試

序列號數據(封裝數據)

public static void main(String[] args) {
		FirstProtobuf.testBuf.Builder builder = FirstProtobuf.testBuf.newBuilder();
		builder.setID(777);
		builder.setName(0, "");
		List<String> values = new ArrayList<String>();
		values.add("aaa");
		values.add("aba");
		values.add("baa");
		values.add("acc");
		builder.addAllName(values);
		
		FirstProtobuf.testBuf info = builder.build();
		byte[] result = info.toByteArray();
		System.out.println(result.toString());
		TestAlone.getData(result);
	}
反序列化數據

public static void getData(byte[] result) {
		try {
			FirstProtobuf.testBuf testBuf = FirstProtobuf.testBuf.parseFrom(result);
			System.out.println(testBuf);
			System.out.println(FirstProtobuf.testBuf.PhoneType.HOME);//這里使用枚舉
		} catch (InvalidProtocolBufferException e) {
			e.printStackTrace();
		}
	}
好了,到這里初體驗完,事實上不難的,我剛開始時一直沒有理解這個protobuf究竟是干什么的,直到我把整個流程跑通了后才理解,它就是一個封裝數據(二進制)協議,通過這種方式封裝數據更小,效率更高



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM