<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      protobuf那些事

      大家好,俺又來寫博客了.......上次劇情預告說,這次會寫hive的博客.......好吧,那俺就不打算寫hive了.......老碼農路子就是要野(本人不老,不能說得影響了找女票)......這次咱們玩什么呢,我之前就看重了一個比較好玩的小玩意兒,那就是來自google的技術,protobuf.

      上次的博客我看了之后很失望啊,閱讀數并不高....我在想是不是大家對hadoop之類的并不感興趣,所以就先換換口味吧.Google Protocol Buffer( 簡稱 Protobuf) 是 Google 公司內部的混合語言數據標準,目前已經正在使用的有超過 48,162 種報文格式定義和超過 12,183 個 .proto 文件。他們用于 RPC 系統和持續數據存儲系統。Protocol Buffers 是一種輕便高效的結構化數據存儲格式,可以用于結構化數據串行化,或者說序列化。它很適合做數據存儲或 RPC 數據交換格式。可用于通訊協議、數據存儲等領域的語言無關、平臺無關、可擴展的序列化結構數據格式。目前提供了 C++、Java、Python 三種語言的 API。

      ok,這就是protubuf的一些比較抽象的介紹,不過簡單地說,protobuf其實就是一種數據傳輸的格式,事實上,我們需要知道pb這種格式用來傳輸數據到底會給我們帶來如何的好處.我們可以拿pb格式和json做對比.其實json這種數據傳輸的格式大家應該非常熟悉.但是json有什么不好的呢,首先json大,json格式是字符串形式,和壓縮為二進制的pb格式肯定是要來的大的.此外,json很坑,因為需要對不同的語言編寫json解析的程序.......php和python自然可以比較輕松的解析,java就坑了.......而且這些解析器的性能并一致,有好有壞.pb因為是大廠的技術嘛,人家搞一個編譯器,編譯為c++,java,python的解析代碼,不就搞定了.......好吧,大廠技術就是雄厚.......我等也只能仰望.....(老子要是有時間,也去寫一個)....

      廢話不多說,直接搞起來.首先,你要去下載pb的tar包.至于安裝包在哪里,少年郎,去google上找吧........我裝的是2.6.1版,安裝非常簡單.

      1 tar zxvf protobuf-2.6.1.tar.gz
      2  cd protobuf-2.6.1
      3 ./configure
      4 make
      5 make check
      6 make install

      這個編譯的過程依舊是無比的漫長.......很懷念大一的時候,寫個hello world,一秒不到就編譯完成,然后很快就能輸出結果的那種快樂的時光.........人的一生就是在等待中度過,等待一個可以白頭到老的人,等待一份可以吃飽飯的工作,等待有一天,能夠成為想成為的那個人.......其實等待是因為有希望,沒有希望,等待似乎就沒有意義了......所以,我一直在想,女票是會有的,飯也可以吃飽的,人不能沒有希望........

      ok,我們安裝完了,來看看有沒有安裝上吧......

      1 protoc --version

      返回:libprotoc 2.6.1. 這樣,就安裝成功了.

      然后我們怎么用這個工具呢?

      1. 首先,我們要做的是,定義一套.proto格式的消息的定義文件.我們在具體的使用中來慢慢來港如何書寫這個proto綴的文件.
      1 message student{
      2     required int64 sid = 1;//學生id
      3     required string name = 2;//學生姓名
      4 }

        這里面我們發現:

      • message類似于C里面的struct,表示我們定義的是一個消息類型.
      • studeng是具體的類型名稱.
      • required是表示這個字段是必須賦值的.
      • int64和string是該字段的類型.
      • =后面的數字表示是該字段在二進制文件中的序號,name為2,表示它一定在sid的后面.

        現在我們如果想要加上一個性別的字段和年齡的字段,性別的字段是enum類型.年齡類型是int32,怎喵加呢?很簡單.

       1 enum Sex{
       2     MALE = 1;
       3     FEMALE = 2;
       4 }
       5 
       6 message Student{
       7     required int64 sid = 1;//學生id
       8     required string name = 2;//學生姓名
       9     optional Sex sex = 3; //學生性別
      10     optional int32 age = 4;//學生年紀
      11 }

        easy啊.等等,現在我們又有一個消息,比如我們有個班級的消息,希望能夠列出里面每個學生的這些基本信息,怎么搞呢?

        首先,我們需要定義一個班級的消息.

      1 message Banji{
      2     required int64 cid = 1;//班級的id
      3     required string cname = 2;//班級的編號
      4     repeated Student students = 3;//學生
      5 }

        這里我們要注意幾個點:

      • required前綴表示該字段為必要字段,既在序列化和反序列化之前該字段必須已經被賦值。與此同時,在Protocol Buffer中還存在另外兩個類似的關鍵字,optional和repeated,帶有這兩種限定符的消息字段則沒有required字段這樣的限制。
      • 標簽值為1到15的字段在編碼時可以得到優化,既標簽值和類型信息僅占有一個byte.標簽范圍是16到2047的將占有兩個bytes,而ProtocolBuffer可以支持的字段數量則為2的29次方減一。有鑒于此,我們在設計消息結構時,可以盡可能考慮讓repeated類型的字段標簽位于1到15之間,這樣便可以有效的節省編碼后的字節數量。
      • 在每個消息中必須至少留有一個required類型的字段.
      • 如果打算在原有消息協議中添加新的字段,同時還要保證老版本的程序能夠正常讀取或寫入,那么對于新添加的字段必須是optional或repeated。道理非常簡單,老版本程序無法讀取或寫入新增的required限定符的字段。
      • 在原有的消息中,不能移除已經存在的required字段,optional和repeated類型的字段可以被移除,但是他們之前使用的標簽號必須被保留,不能被新的字段重用。
      • int32、uint32、int64、uint64和bool等類型之間是兼容的,sint32和sint64是兼容的,string和bytes是兼容的,fixed32和sfixed32,以及fixed64和sfixed64之間是兼容的,這意味著如果想修改原有字段的類型時,為了保證兼容性,只能將其修改為與其原有類型兼容的類型,否則就將打破新老消息格式的兼容性。

        這里還有一個問題,Banji這個消息要用到Student的定義,我們可以回憶一下java中的處理方式,這種互相定義之間的依賴可以用package和import來解決.這樣,我們可以給出完整的.proto的定義方式:

        test.student.proto

      package test;
      option java_package = "com.songfy.pb";
      option java_outer_classname = "StudentProtobuf";
      enum Sex{
              MALE = 1;
              FEMALE = 2;
      }
      
      message Student{
              required int64 sid = 1;//學生id
              required string name = 2;//學生姓名
              optional Sex sex = 3; //學生性別
              optional int32 age = 4;//學生年紀
      }

        test.banji.proto

      1 import "test.student.proto";
      2 package test;
      3 option java_package = "com.songfy.pb";
      4 option java_outer_classname = "BanjiProtobuf";
      5 message Banji{
      6         required int64 cid = 1;//班級的id
      7         required string cname = 2;//班級的編號
      8         repeated Student students = 3;//學生
      9 }

      ok,這樣我們就把我們的消息類型定義好了....那么如何寫代碼呢?下面我們細細道來.

        2.編譯.proto

            我們這里用java來做示例,C++也成,但是還是java稍微方便一下,大家可以用C++試一試,python呢就算了,俺不太會python,也沒有興趣去學,個人喜好,勿噴,嗯,就這樣.ok,那現在我們就來編譯這個玩意兒.

      1 protoc --java_out="/usr/home/feng/protos/src" test.banji.proto test.student.proto 

        吊炸天,瞬間產生了1000多行代碼,來自google的技術,四國一!

        不過現在問題來了,這代碼怎么用?這代碼看都看不懂,怎么用呢?不要驚慌,一定不要驚慌.......先靠到你的elipse再說....然后你就會發現一大堆的錯誤......嗯........

        這個解決的方法很簡單,將protobuf-java-2.6.1.jar下載下來,加入到我們的path中,那我們的問題就都解決了.

        接下來,我們來看看如何寫代碼.嗯,終于到了寫代碼的時候了........

        

       1 package com.songfy.pb;
       2 
       3 import java.io.FileInputStream;
       4 import java.io.FileOutputStream;
       5 import java.io.IOException;
       6 import java.util.ArrayList;
       7 import java.util.List;
       8 
       9 import com.songfy.pb.BanjiProtobuf.Banji;
      10 import com.songfy.pb.StudentProtobuf.Sex;
      11 import com.songfy.pb.StudentProtobuf.Student;
      12 
      13 public class Main {
      14 
      15     public static void main(String[] args) throws IOException {
      16         
      17         //獲取student的build sb
      18         Student.Builder sb = Student.newBuilder();
      19         //加入兩個學生
      20         sb.setSid(110);
      21         sb.setName("shuaiguo");
      22         sb.setSex(Sex.MALE);
      23         sb.setAge(11);
      24         
      25         List<Student> list = new ArrayList<Student>();
      26         list.add(sb.build());
      27         
      28         sb = Student.newBuilder();
      29         sb.setSid(119);
      30         sb.setName("lilei");
      31         sb.setSex(Sex.FEMALE);
      32         sb.setAge(20);
      33         
      34         list.add(sb.build());
      35         
      36         //產生一個班級
      37         Banji.Builder bb = Banji.newBuilder();
      38         bb.setCid(13);
      39         bb.setCname("dafengqi");
      40         bb.addAllStudents(list);
      41         
      42         //刷入到文件中
      43          FileOutputStream fos = new FileOutputStream("C:/Users/songfy/Desktop/test.protoout");
      44          bb.build().writeTo(fos);
      45          fos.close();
      46          
      47          //從文件讀回
      48          Banji bb1 = Banji.parseFrom(new FileInputStream("C:/Users/songfy/Desktop/test.protoout"));
      49          System.out.println(bb1.getCid() + "\t" + bb1.getCname());
      50          for(Student s: bb1.getStudentsList()){
      51              System.out.println(s.getSid() + "\t" + s.getName() + "\t" + s.getSex() + "\t" + s.getAge());
      52          }
      53 
      54     }
      55 
      56 }

      這就是我們代碼了,似乎非常easy啊........

      這樣,我們可以看到輸出結果為:

      13 dafengqi
      110 shuaiguo MALE 11
      119 lilei FEMALE 20

       

      這正是我們想要的,這次的博客時間就到此為止了,我們下次再見........2333333......2333333.......

       

      posted @ 2015-08-15 15:39  逝雪  閱讀(3655)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 热久久这里只有精品国产| 柳林县| 亚洲人成网站在线播放动漫| 日韩精品自拍偷拍一区二区| 久久99九九精品久久久久蜜桃| 远安县| 亚洲天堂成人黄色在线播放| 人妻少妇偷人无码视频| 国产免费午夜福利在线播放| 国产精品久久一区二区三区| 成在人线av无码免费| 亚洲国产高清精品线久久| 枣庄市| 日韩在线视频一区二区三| 亚洲AV网一区二区三区| 文水县| 国内自拍第一区二区三区| 日本一道一区二区视频| 欧美一区二区三区性视频| 18禁免费无码无遮挡网站| 高清精品视频一区二区三区| 午夜精品一区二区三区在线观看| 麻豆成人精品国产免费| 色悠悠国产精品免费观看| 国产一区二区日韩在线| 亚洲综合另类小说色区一 | 国产色悠悠在线免费观看 | 乱妇乱女熟妇熟女网站| 中文字幕色av一区二区三区| 色综合一本到久久亚洲91| 国产国拍精品av在线观看| 国产精品中文第一字幕| 国产成人精品成人a在线观看| 亚洲AV无码一区二区一二区色戒| 性欧美VIDEOFREE高清大喷水| 国产成人剧情AV麻豆果冻| 亚洲乱理伦片在线观看中字| 少妇熟女视频一区二区三区| 国产一区二区三区高清视频| 国产一区二区四区不卡| 亚洲精品~无码抽插|