久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

Protocol Buffer技術(shù)詳解(Java實(shí)例)

 開(kāi)心豆豆2010 2013-09-25

  該篇Blog和上一篇(C++實(shí)例)基本相同,,只是面向于我們團(tuán)隊(duì)中的Java工程師,,畢竟我們項(xiàng)目的前端部分是基于Android開(kāi)發(fā)的,而且我們研發(fā)團(tuán)隊(duì)中目前主要使用的開(kāi)發(fā)語(yǔ)言就是C++,、Java和Python,,其中Python主要用于編寫各種工具程序,。然而為了保證該篇Blog的完整性和獨(dú)立性,我仍然會(huì)將上一篇Blog中已經(jīng)出現(xiàn)的內(nèi)容再一次贅述,,同時(shí)對(duì)于Java中特有的部分也會(huì)著重介紹,。
    
      一、生成目標(biāo)語(yǔ)言代碼,。
      下面的命令幫助我們將MyMessage.proto文件中定義的一組Protocol Buffer格式的消息編譯成目標(biāo)語(yǔ)言(Java)的代碼,。至于消息的內(nèi)容,我們會(huì)在后面以分段的形式逐一列出,,同時(shí)也會(huì)在附件中給出所有源代碼,。
      protoc -I=./message --java_out=./src ./MyMessage.proto
      從上面的命令行參數(shù)中可以看出,待編譯的文件為MyMessage.proto,,他存放在當(dāng)前目錄的message子目錄下,。--java_out參數(shù)則指示編譯工具我們需要生成目標(biāo)語(yǔ)言是java,輸出目錄是當(dāng)前目錄的src子目錄,。這里需要補(bǔ)充說(shuō)明的是,,因?yàn)樵贛yMessage.proto文件中定義了option java_package = "com.lsk.lyphone"的文件級(jí)選項(xiàng),所以輸出的目前是src/com/lsk/lyphone,,生成的目標(biāo)代碼文件名是MyMessage.java,。
    
      二、簡(jiǎn)單message生成的Java代碼,。
      這里先定義一個(gè)最簡(jiǎn)單的message,,其中只是包含原始類型的字段。
      option java_package = "com.lsk.lyphone";
      option java_outer_classname = "LYPhoneMessage";
      option optimize_for = LITE_RUNTIME;
      message LogonReqMessage {
          required int64 acctID = 1;
          required string passwd = 2;
      }
      對(duì)于選項(xiàng)java_packagejava_outer_classname的功能,,我們已經(jīng)在之前的一篇Blog(語(yǔ)言規(guī)范)中進(jìn)行了清晰的闡述,,這里就不在另行介紹了。然而對(duì)于選項(xiàng)optimize_for,,這里將結(jié)合本例給出一些實(shí)用性描述,。
      當(dāng)前.proto文件中該選項(xiàng)的值為LITE_RUNTIME,因此由該.proto文件生成的所有Java類的父類均為com.google.protobuf.GeneratedMessageLite,,而非com.google.protobuf.GeneratedMessage,,同時(shí)與之對(duì)應(yīng)的Builder類則均繼承自com.google.protobuf.MessageLiteOrBuilder,而非com.google.protobuf.MessageOrBuilder,。在之前的博客中已經(jīng)給出了一些簡(jiǎn)要的說(shuō)明,,MessageLite接口是Message的父接口,在MessageLite中將缺少Protocol Buffer對(duì)反射的支持,,而此功能均在Message接口中提供了接口規(guī)范,,同時(shí)又在其實(shí)現(xiàn)類GeneratedMessage中給予了最小功能的實(shí)現(xiàn)。對(duì)于我們的項(xiàng)目而言,,整個(gè)系統(tǒng)相對(duì)比較封閉,,不會(huì)和更多的外部程序進(jìn)行交互,與此同時(shí),,我們的客戶端部分又是運(yùn)行在Android平臺(tái),,有鑒于此,我們考慮使用LITE版本的Protocol Buffer,。這樣不僅可以得到更高編碼效率,,而且生成代碼編譯后所占用的資源也會(huì)更少,至于反射所能帶來(lái)的靈活性和極易擴(kuò)展性,,對(duì)于該項(xiàng)目而言完全可以忽略,。下面我們來(lái)看一下由message LogonReqMessage生成的Java類的部分聲明,以及常用方法的說(shuō)明性注釋,。
      在做各種case的對(duì)比性分析之前必須要事先聲明的是,,Protocol Buffer針對(duì)Java語(yǔ)言所生成的代碼和C++相比存在一個(gè)非常重要的差別,即為每個(gè)消息均會(huì)生成一個(gè)Builder接口和一個(gè)與消息對(duì)應(yīng)的實(shí)現(xiàn)類,,該實(shí)現(xiàn)類又將同時(shí)實(shí)現(xiàn)生成的Builder接口和擴(kuò)展Protocol Buffer內(nèi)置的GeneratedMessageLite(或GeneratedMessage)類,。這一點(diǎn)對(duì)于Protocol Buffer而言,是巧妙的使用了設(shè)計(jì)模式中的Builder模式,。換言之,,對(duì)于所有消息字段的修改操作均需要通過(guò)與其對(duì)應(yīng)的Builder接口輔助完成。相信我們會(huì)通過(guò)對(duì)下面用例的學(xué)習(xí)可以得到更為清楚的認(rèn)識(shí),。

復(fù)制代碼
  1     //用于修改LogonReqMessage消息字段的輔助Builder接口,。
  2     //該接口會(huì)為消息中的每個(gè)字段均提供getter和setter方法。
  3     public interface LogonReqMessageOrBuilder
  4         extends com.google.protobuf.MessageLiteOrBuilder {
  5     
  6         // required int64 acctID = 1;
  7         boolean hasAcctID();
  8         long getAcctID();
  9         
 10         // required string passwd = 2;
 11         boolean hasPasswd();
 12         String getPasswd();
 13     }
 14     //該類為final類,,即不可以在被子類化了,。這一點(diǎn)在Protocol Buffer的官方文檔中給予了明確
 15     //的說(shuō)明,因?yàn)樽宇惢瘜?huì)破壞序列化和反序列化的過(guò)程,。
 16     public static final class LogonReqMessage extends
 17         com.google.protobuf.GeneratedMessageLite
 18         implements LogonReqMessageOrBuilder {
 19         
 20         // Use LogonReqMessage.newBuilder() to construct.
 21         // 由于所有構(gòu)造函數(shù)均為私有方法,,由此可見(jiàn),我們不能直接new LogonReqMessage的對(duì)象
 22         // 實(shí)例,,而是只能通過(guò)與其對(duì)應(yīng)Builder來(lái)構(gòu)造,或是直接通過(guò)反序列化的方式生成,。
 23         private LogonReqMessage(Builder builder) {
 24             super(builder);
 25         }
 26         //該靜態(tài)方法為該類Builder接口的工廠方法,。返回的Builder實(shí)現(xiàn)類在完成各個(gè)字段的
 27         //初始化后,,通過(guò)build()方法返回與其對(duì)應(yīng)的消息實(shí)現(xiàn)類,即LogonReqMessage,。
 28         public static Builder newBuilder() { return Builder.create(); }
 29         //通過(guò)該類的對(duì)象獲取與其對(duì)應(yīng)的Builder類對(duì)象,,一般用于通過(guò)Builder類完成消息字段的修改。
 30         public Builder toBuilder() { return newBuilder(this); }
 31 
 32         private LogonReqMessage(boolean noInit) {}
 33         //判斷當(dāng)前對(duì)象的所有字段是否都已經(jīng)被初始化,。
 34         public final boolean isInitialized() {
 35             ... ...
 36         }
 37         //獲取已經(jīng)被初始化后的對(duì)象序列化時(shí)所占用的字節(jié)空間,。
 38         public int getSerializedSize() {
 39             ... ...
 40         }
 41         //從內(nèi)存中飯序列化LogonReqMessage對(duì)象。
 42         //Protocol Buffer中還提供其他一些接口方法,,用于從不同的數(shù)據(jù)源反序列化對(duì)象,。
 43         public static com.lsk.lyphone.LYPhoneMessage.LogonReqMessage parseFrom(byte[] data)
 44             throws com.google.protobuf.InvalidProtocolBufferException {
 45             return newBuilder().mergeFrom(data).buildParsed();
 46         }
 47         //功能和上一個(gè)函數(shù)相同,只是輸入源改為InputStream接口,。
 48         public static com.lsk.lyphone.LYPhoneMessage.LogonReqMessage parseFrom(java.io.InputStream input)
 49             throws java.io.IOException {
 50             return newBuilder().mergeFrom(input).buildParsed();
 51         }
 52         
 53         // required int64 acctID = 1;
 54         // 下面的靜態(tài)變量對(duì)應(yīng)于該字段在.proto中定義的標(biāo)簽號(hào),。該變量的命名規(guī)則為:字段(全部大寫) + _FIELD_NUMBER。
 55         public static final int ACCTID_FIELD_NUMBER = 1;
 56         public boolean hasAcctID() {
 57             return ((bitField0_ & 0x00000001) == 0x00000001);
 58         }
 59         public long getAcctID() {
 60             return acctID_;
 61         }
 62 
 63         // required string passwd = 2;
 64         public static final int PASSWD_FIELD_NUMBER = 2;
 65         public boolean hasPasswd() {
 66             return ((bitField0_ & 0x00000002) == 0x00000002);
 67         }
 68         public String getPasswd() {
 69             ... ... 
 70         }
 71         //每一個(gè)Message類都會(huì)包含一個(gè)靜態(tài)內(nèi)部類,,即與之對(duì)應(yīng)的Builder類,。上面代碼中所涉及的Builder類均為該內(nèi)部類。
 72         public static final class Builder extends
 73             com.google.protobuf.GeneratedMessageLite.Builder<
 74             com.lsk.lyphone.LYPhoneMessage.LogonReqMessage, Builder>
 75             implements com.lsk.lyphone.LYPhoneMessage.LogonReqMessageOrBuilder {
 76             //清空當(dāng)前對(duì)象中的所有設(shè)置,。調(diào)用該函數(shù)之后,,本例中的hasAcctID和hasPasswd都會(huì)返回false。    
 77             public Builder clear() {
 78                 super.clear();
 79                 acctID_ = 0L;
 80                 bitField0_ = (bitField0_ & ~0x00000001);
 81                 passwd_ = "";
 82                 bitField0_ = (bitField0_ & ~0x00000002);
 83                 return this;
 84             }
 85             //克隆出一個(gè)Builder對(duì)象,。
 86             public Builder clone() {
 87                 return create().mergeFrom(buildPartial());
 88             }
 89             public com.lsk.lyphone.LYPhoneMessage.LogonReqMessage build() {
 90                 com.lsk.lyphone.LYPhoneMessage.LogonReqMessage result = buildPartial();
 91                 if (!result.isInitialized()) {
 92                     throw newUninitializedMessageException(result);
 93                 }
 94                 return result;
 95             }
 96             // Builder類中修改外部消息類的方法,。
 97             // required int64 acctID = 1;
 98             public boolean hasAcctID() {
 99                 return ((bitField0_ & 0x00000001) == 0x00000001);
100             }
101             public long getAcctID() {
102                 return acctID_;
103             }
104             //設(shè)置AcctID字段,該函數(shù)調(diào)用后hasAcctID函數(shù)將返回true,。
105             //這里之所以讓返回值為Builder對(duì)象,,就是可以讓調(diào)用者在一條代碼中方便的連續(xù)修改多個(gè)字段,
106             //如:myMessage.setAcctID(100).setPasswd("MyName");
107             public Builder setAcctID(long value) {
108                 bitField0_ |= 0x00000001;
109                 acctID_ = value;
110                 return this;
111             }
112             //清空AcctID字段,,該函數(shù)調(diào)用后hasAcctID函數(shù)返回false,。
113             //這里之所以讓返回值為Builder對(duì)象,就是可以讓調(diào)用者在一條代碼中方便的連續(xù)清空多個(gè)字段,,
114             //如:myMessage.clearAcctID().clearPasswd();
115             public Builder clearAcctID() {
116                 bitField0_ = (bitField0_ & ~0x00000001);
117                 acctID_ = 0L;
118                 return this;
119             }
120       
121             // required string passwd = 2;
122             public boolean hasPasswd() {
123                 return ((bitField0_ & 0x00000002) == 0x00000002);
124             }
125             public String getPasswd() {
126                 ... ...        
127             }
128             public Builder setPasswd(String value) {
129                 ... ...
130             }
131             public Builder clearPasswd() {
132                 bitField0_ = (bitField0_ & ~0x00000002);
133                 passwd_ = getDefaultInstance().getPasswd();
134                 return this;
135             }
136             void setPasswd(com.google.protobuf.ByteString value) {
137                 bitField0_ |= 0x00000002;
138                 passwd_ = value;
139             }
140         }
141     }            
復(fù)制代碼

      在上面生成的代碼中并沒(méi)有列出與序列化相關(guān)的函數(shù),,這部分代碼基本都是在父類中實(shí)現(xiàn)的,我們將在下面的例子中給出一些最基本的用法,,有興趣的開(kāi)發(fā)者可以直接看Protocol Buffer中的源碼,,這部分代碼比較通俗易懂。
      下面是讀寫LogonReqMessage對(duì)象的Java測(cè)試代碼和說(shuō)明性注釋,。

復(fù)制代碼
 1     private static void testSimpleMessage() {
 2         System.out.println("==================This is simple message.================");
 3         //如前所述,,不能直接構(gòu)造該消息類對(duì)象,只能通過(guò)他的內(nèi)部Builder類構(gòu)造并完成所有字段的初始化,。
 4         LogonReqMessage.Builder logonReqBuilder = LogonReqMessage.newBuilder();
 5         logonReqBuilder.setAcctID(20);
 6         logonReqBuilder.setPasswd("Hello World");
 7         //builder對(duì)象初始化完畢后,,再通過(guò)build方法生成與之對(duì)應(yīng)的消息類對(duì)象,。
 8         LogonReqMessage logonReq = logonReqBuilder.build();
 9         int length = logonReq.getSerializedSize();
10         System.out.println("The result length is " + length);
11         //直接序列化到內(nèi)存中,之后可對(duì)該內(nèi)存進(jìn)行二次加工后再寫到本地文件或發(fā)送到遠(yuǎn)端,,如加密,。
12         byte[] buf = logonReq.toByteArray();
13 
14         try {
15             LogonReqMessage logonReq2 = LogonReqMessage.parseFrom(buf);
16             System.out.println("acctID = " + logonReq2.getAcctID() + "\tpassword = " + logonReq2.getPasswd());
17         } catch (InvalidProtocolBufferException e) {
18             e.printStackTrace();
19         }
20         //需要說(shuō)明的是,文件中的內(nèi)容是由之前C++實(shí)例代碼寫入的,,這里這樣寫主要是一種驗(yàn)證。
21         System.out.println("Reading data from local file generated by C++");
22         try {
23             LogonReqMessage logonReq3 = LogonReqMessage.parseFrom(new FileInputStream("C:/Mine/LogonReq.dat"));
24             System.out.println("acctID = " + logonReq3.getAcctID() + "\tpassword = " + logonReq3.getPasswd());
25         } catch (FileNotFoundException e) {
26             e.printStackTrace();
27         } catch (IOException e) {
28             e.printStackTrace();
29         }
30     }
復(fù)制代碼

      三,、嵌套message生成的Java代碼,。
      enum UserStatus {
          OFFLINE = 0;
          ONLINE = 1;
      }
      enum LoginResult {
          LOGON_RESULT_SUCCESS = 0;
          LOGON_RESULT_NOTEXIST = 1;
          LOGON_RESULT_ERROR_PASSWD = 2;
          LOGON_RESULT_ALREADY_LOGON = 3;
          LOGON_RESULT_SERVER_ERROR = 4;
      }
      message UserInfo {
          required int64 acctID = 1;
          required string name = 2;
          required UserStatus status = 3;
      }
      message LogonRespMessage {
          required LoginResult logonResult = 1;
          required UserInfo userInfo = 2; //這里嵌套了UserInfo消息。
      }
      對(duì)于上述消息生成的Java代碼,,UserInfo因?yàn)橹皇前嗽碱愋妥侄?,因此和上例中的LogonReqMessage沒(méi)有太多的差別,這里也就不在重復(fù)列出了,。由于LogonRespMessage消息中嵌套了UserInfo類型的字段,,在這里我們將僅僅給出該消息生成的Java代碼和關(guān)鍵性注釋。

復(fù)制代碼
 1     public static final class LogonRespMessage extends
 2         com.google.protobuf.GeneratedMessageLite
 3         implements LogonRespMessageOrBuilder {
 4         
 5         //Message類的通用性函數(shù)定義,。
 6         ... ...
 7         
 8         // required .LoginResult logonResult = 1;
 9         public static final int LOGONRESULT_FIELD_NUMBER = 1;
10         public boolean hasLogonResult() {
11             return ((bitField0_ & 0x00000001) == 0x00000001);
12         }
13         public com.lsk.lyphone.LYPhoneMessage.LoginResult getLogonResult() {
14             return logonResult_;
15         }
16         
17         // required .UserInfo userInfo = 2;
18         public static final int USERINFO_FIELD_NUMBER = 2;
19         public boolean hasUserInfo() {
20             return ((bitField0_ & 0x00000002) == 0x00000002);
21         }
22         public com.lsk.lyphone.LYPhoneMessage.UserInfo getUserInfo() {
23             return userInfo_;
24         }
25         //Message類的通用性函數(shù)定義,。可參照上一小節(jié)中的代碼和注釋,。
26         ... ...
27         
28         public static final class Builder extends
29             com.google.protobuf.GeneratedMessageLite.Builder<
30             com.lsk.lyphone.LYPhoneMessage.LogonRespMessage, Builder>
31             implements com.lsk.lyphone.LYPhoneMessage.LogonRespMessageOrBuilder {
32 
33             //一些適用于絕大多數(shù)Builder對(duì)象的通用性方法,。
34             ... ...
35             
36             //當(dāng)前示例中Builder生成的代碼和上一小節(jié)中生成的代碼非常類似,這里就不一一贅述了,。
37             //和前面的例子相比一個(gè)重要的差別是setUserInfo函數(shù)多提供了一種函數(shù)簽名,,其參數(shù)為
38             //UserInfo類的Builder對(duì)象。這樣調(diào)用者在使用時(shí)可以直接將Builder對(duì)象作為參數(shù)傳入,。
39             public Builder setUserInfo(com.lsk.lyphone.LYPhoneMessage.UserInfo.Builder builderForValue) {
40                 userInfo_ = builderForValue.build();
41                 bitField0_ |= 0x00000002;
42                 return this;
43             }
44         }
45     }
復(fù)制代碼

      下面是讀寫LogonRespMessage對(duì)象的Java測(cè)試代碼和說(shuō)明性注釋,。

復(fù)制代碼
 1     private static void testNestedMessage() {
 2         System.out.println("==================This is nested message.================");
 3         LogonRespMessage.Builder logonRespBuilder = LogonRespMessage.newBuilder();
 4         logonRespBuilder.setLogonResult(LoginResult.LOGON_RESULT_SUCCESS);
 5         UserInfo.Builder userInfo = UserInfo.newBuilder();
 6         userInfo.setAcctID(200);
 7         userInfo.setName("Tester");
 8         userInfo.setStatus(UserStatus.OFFLINE);
 9         //這里也可以直接傳遞userInfo對(duì)象作為參數(shù)。因?yàn)長(zhǎng)ogonRespBuilder類提供了setUserInfo的方法重載,。
10         logonRespBuilder.setUserInfo(userInfo.build());
11         LogonRespMessage logonResp = logonRespBuilder.build();
12         int length = logonResp.getSerializedSize();
13         System.out.println("The result length is " + length);
14         byte[] buf = logonResp.toByteArray();
15 
16         try {
17             LogonRespMessage logonResp2 = LogonRespMessage.parseFrom(buf);
18             UserInfo userInfo2 = logonResp2.getUserInfo();
19             System.out.println("LogonResult = " + logonResp2.getLogonResult().toString() + " acctID = " 
20                     + userInfo2.getAcctID() + " name = " + userInfo2.getName() + " status = " + userInfo2.getStatus().toString());
21         } catch (InvalidProtocolBufferException e) {
22             e.printStackTrace();
23         }
24         System.out.println("Reading data from local file generated by C++");
25         try {
26             LogonRespMessage logonResp3 = LogonRespMessage.parseFrom(new FileInputStream("C:/Mine/LogonResp.dat"));
27             UserInfo userInfo3 = logonResp3.getUserInfo();
28             System.out.println("LogonResult = " + logonResp3.getLogonResult().toString() + " acctID = " 
29                     + userInfo3.getAcctID() + " name = " + userInfo3.getName() + " status = " + userInfo3.getStatus().toString());
30         } catch (FileNotFoundException e) {
31             e.printStackTrace();
32         } catch (IOException e) {
33             e.printStackTrace();
34         }
35     }
復(fù)制代碼

      四,、repeated嵌套message生成的Java代碼。
      message BuddyInfo {
          required UserInfo userInfo = 1;
          required int32 groupID = 2;
      }
      message RetrieveBuddiesResp {
          required int32 buddiesCnt = 1;
          repeated BuddyInfo buddiesInfo = 2;
      }
      對(duì)于上述消息生成的代碼,,我們將只是針對(duì)RetrieveBuddiesResp消息所對(duì)應(yīng)的Java代碼進(jìn)行詳細(xì)說(shuō)明,,其余部分和前面小節(jié)的例子基本相同,可直接參照,。而對(duì)于RetrieveBuddiesResp類中的代碼,,我們也僅僅是對(duì)buddiesInfo字段生成的代碼進(jìn)行更為詳細(xì)的解釋。

復(fù)制代碼
 1     public static final class RetrieveBuddiesResp extends
 2         com.google.protobuf.GeneratedMessageLite
 3         implements RetrieveBuddiesRespOrBuilder {
 4         //這里均為Protocol Buffer生成的通用性代碼,。
 5         ... ...
 6         // repeated .BuddyInfo buddiesInfo = 2;
 7         public static final int BUDDIESINFO_FIELD_NUMBER = 2;
 8         //對(duì)于repeated類型的字段,,均返回類型參數(shù)為字段類型的泛型容器對(duì)象,。
 9         public java.util.List<com.lsk.lyphone.LYPhoneMessage.BuddyInfo> getBuddiesInfoList() {
10             return buddiesInfo_;
11         }
12         public java.util.List<? extends com.lsk.lyphone.LYPhoneMessage.BuddyInfoOrBuilder> getBuddiesInfoOrBuilderList() {
13             return buddiesInfo_;
14         }
15         public int getBuddiesInfoCount() {
16             return buddiesInfo_.size();
17         }
18         public com.lsk.lyphone.LYPhoneMessage.BuddyInfo getBuddiesInfo(int index) {
19             return buddiesInfo_.get(index);
20         }
21         public com.lsk.lyphone.LYPhoneMessage.BuddyInfoOrBuilder getBuddiesInfoOrBuilder(int index) {
22             return buddiesInfo_.get(index);
23         }
24         
25         //這里仍有一些Protocol Buffer生成的通用性代碼。
26         ... ...
27         
28         public static final class Builder extends
29             com.google.protobuf.GeneratedMessageLite.Builder<
30             com.lsk.lyphone.LYPhoneMessage.RetrieveBuddiesResp, Builder>
31             implements com.lsk.lyphone.LYPhoneMessage.RetrieveBuddiesRespOrBuilder {
32             
33             //這里僅列出和操作repeated字段相關(guān)的方法,,其他的方法和前面的例子基本一致,。
34             // repeated .BuddyInfo buddiesInfo = 2;
35             //本來(lái)打算給出比較詳細(xì)的說(shuō)明,但是看到Google為每個(gè)函數(shù)的命名之后就放棄這個(gè)想法,,
36             //這樣一來(lái)不僅可以避免畫蛇添足,,而且也節(jié)省了時(shí)間。:)            
37             public java.util.List<com.lsk.lyphone.LYPhoneMessage.BuddyInfo> getBuddiesInfoList() {
38                 return java.util.Collections.unmodifiableList(buddiesInfo_);
39             }
40             public int getBuddiesInfoCount() {
41                 return buddiesInfo_.size();
42             }
43             public com.lsk.lyphone.LYPhoneMessage.BuddyInfo getBuddiesInfo(int index) {
44                 return buddiesInfo_.get(index);
45             }
46             public Builder setBuddiesInfo(int index, com.lsk.lyphone.LYPhoneMessage.BuddyInfo value) {
47                 ... ...
48             }
49             public Builder setBuddiesInfo(int index, com.lsk.lyphone.LYPhoneMessage.BuddyInfo.Builder builderForValue) {
50                 ... ...
51             }
52             public Builder addBuddiesInfo(com.lsk.lyphone.LYPhoneMessage.BuddyInfo value) {
53                 ... ...
54             }
55             public Builder addBuddiesInfo(int index, com.lsk.lyphone.LYPhoneMessage.BuddyInfo value) {
56                 ... ...
57             }
58             public Builder addBuddiesInfo(com.lsk.lyphone.LYPhoneMessage.BuddyInfo.Builder builderForValue) {
59                 ... ...
60             }
61             public Builder addBuddiesInfo(
62                 int index, com.lsk.lyphone.LYPhoneMessage.BuddyInfo.Builder builderForValue) {
63                 ... ...
64             }
65             public Builder addAllBuddiesInfo(
66                 java.lang.Iterable<? extends com.lsk.lyphone.LYPhoneMessage.BuddyInfo> values) {
67                 ... ...
68             }
69             public Builder clearBuddiesInfo() {
70                 ... ...
71             }
72             public Builder removeBuddiesInfo(int index) {
73                 ... ...
74             }
75         }
76     }
復(fù)制代碼

      下面是讀寫RetrieveBuddiesResp對(duì)象的Java測(cè)試代碼和說(shuō)明性注釋,。

復(fù)制代碼
 1     private static void testRepeatedMessage() {
 2         System.out.println("==================This is repeated message.================");
 3         RetrieveBuddiesResp.Builder retrieveBuddiesBuilder = RetrieveBuddiesResp.newBuilder();
 4         retrieveBuddiesBuilder.setBuddiesCnt(2);
 5         BuddyInfo.Builder buddyInfoBuilder = BuddyInfo.newBuilder();
 6         buddyInfoBuilder.setGroupID(20);
 7         UserInfo.Builder userInfoBuilder = UserInfo.newBuilder();
 8         userInfoBuilder.setAcctID(200);
 9         userInfoBuilder.setName("user1");
10         userInfoBuilder.setStatus(UserStatus.OFFLINE);
11         buddyInfoBuilder.setUserInfo(userInfoBuilder.build());
12         retrieveBuddiesBuilder.addBuddiesInfo(buddyInfoBuilder.build());
13         
14         buddyInfoBuilder = BuddyInfo.newBuilder();
15         buddyInfoBuilder.setGroupID(21);
16         userInfoBuilder = UserInfo.newBuilder();
17         userInfoBuilder.setAcctID(201);
18         userInfoBuilder.setName("user2");
19         userInfoBuilder.setStatus(UserStatus.ONLINE);
20         buddyInfoBuilder.setUserInfo(userInfoBuilder);
21         retrieveBuddiesBuilder.addBuddiesInfo(buddyInfoBuilder);
22         RetrieveBuddiesResp buddiesResp = retrieveBuddiesBuilder.build();
23         
24         int length = buddiesResp.getSerializedSize();
25         System.out.println("The result length is " + length);
26         byte[] buf = buddiesResp.toByteArray();
27         
28         try {
29             RetrieveBuddiesResp buddiesResp2 = RetrieveBuddiesResp.parseFrom(buf);
30             System.out.println("BuddiesCount = " + buddiesResp2.getBuddiesCnt());
31             System.out.println("Repeated Size = " + buddiesResp2.getBuddiesInfoCount());
32             for (int i = 0; i < buddiesResp2.getBuddiesInfoCount(); ++i) {
33                 BuddyInfo buddyInfo = buddiesResp2.getBuddiesInfo(i);
34                 UserInfo userInfo = buddyInfo.getUserInfo();
35                 System.out.println("GroupID = " + buddyInfo.getGroupID() + " UserInfo.acctID = " + userInfo.getAcctID()
36                         + " UserInfo.name = " + userInfo.getName() + " UserInfo.status = " + userInfo.getStatus());
37             }
38             
39         } catch (InvalidProtocolBufferException e) {
40             e.printStackTrace();
41         }
42         System.out.println("Reading data from local file generated by C++");
43         try {
44             RetrieveBuddiesResp buddiesResp3 = RetrieveBuddiesResp.parseFrom(new FileInputStream("C:/Mine/RetrieveBuddiesResp.dat"));
45             System.out.println("BuddiesCount = " + buddiesResp3.getBuddiesCnt());
46             System.out.println("Repeated Size = " + buddiesResp3.getBuddiesInfoCount());
47             List<BuddyInfo> buddiesInfo = buddiesResp3.getBuddiesInfoList();
48             for (BuddyInfo buddyInfo : buddiesInfo) {
49                 UserInfo userInfo = buddyInfo.getUserInfo();
50                 System.out.println("GroupID = " + buddyInfo.getGroupID() + " UserInfo.acctID = " + userInfo.getAcctID()
51                         + " UserInfo.name = " + userInfo.getName() + " UserInfo.status = " + userInfo.getStatus());
52             }
53         } catch (FileNotFoundException e) {
54             e.printStackTrace();
55         } catch (IOException e) {
56             e.printStackTrace();
57         }
58     }
復(fù)制代碼

      對(duì)于Java而言,,我們可以通過(guò)Maven工具生成兩個(gè)jar包,其中一個(gè)是protobuf-java-2.4.1.jar,,主要用于optimize_for選項(xiàng)為非LITE_RUNTIME的情況,,而另一個(gè)protobuf-java-2.4.1-lite.jar文件則恰恰與之相反。另外,,我通過(guò)Beyond Compare工具對(duì)這兩個(gè)jar包進(jìn)行了二進(jìn)制比較后發(fā)現(xiàn),,他們是完全相同的。這里之所以仍以LITE版本為例,,主要還是因?yàn)楹椭耙黄狟log(C++實(shí)例)想匹配,。
      最后需要說(shuō)明的是,Protocol Buffer仍然提供了很多其它非常有用的功能,,特別是針對(duì)序列化的目的地,,比如文件流和網(wǎng)絡(luò)流等。與此同時(shí),,也提供了完整的官方文檔和規(guī)范的命名規(guī)則,,在很多情況下,可以直接通過(guò)函數(shù)的名字便可獲悉函數(shù)所完成的工作,。
      該Blog中使用的示例代碼均已附件的方式上傳,,歡迎大家下載并指正。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購(gòu)買等信息,,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請(qǐng)點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多