Golang語言下使用Protocol Buffer教程


代碼倉庫地址

 一、介紹

Protobuf是Google旗下的一款平台無關,語言無關,可擴展的序列化結構數據格式。所以 很適合用做數據存儲和作為不同應用,不同語言之間相互通信的數據交換格式,只要實現相同的協議格式即同一proto文件被編譯成不同的語言版本,加入到各自的工程中去,這樣不同語言就可以解析其他語言通過Protobuf序列化的數據。目前官網提供了C++,Python,JAVA,GO等語言的支持。

相對於JSON和XML具有以下優點:

  • 簡潔

  • 體積小:消息大小只需要XML的1/10 ~ 1⁄3

  • 速度快:解析速度比XML快20 ~ 100倍

  • 使用Protobuf的編譯器,可以生成更容易在編程中使用的數據訪問代碼

  • 更好的兼容性,Protobuf設計的一個原則就是要能夠很好的支持向下或向上兼容

 
注:本文主要注重protobuf的使用,所以省去了下載、安裝的操作步驟。
 
 

二、創建一個test.proto文件並生成test.pb.go文件

syntax = "proto3";  //聲明使用proto3協議

package test;  //包名,通過protoc生成go文件

enum PhoneType{
    HOME = 0;
    WORK = 1;
}

message Phone{  //消息定義的關鍵字
    PhoneType type = 1;
    string number = 2;
}

message Person{
    int32 id = 1;
    string name = 2;
    repeated Phone phones = 3;  //字段可以被重復任意多次(包括0次)
}

message ContactBook{
    repeated Person persons = 1;
}

 

運行如下命令生成test.pb.go文件

> protoc --go_out=. *.proto

 

注意 包名要和文件夾名一致。

 

三、在Go語言中使用Protobuf

package main

import (
    "fmt"
    "io/ioutil"
    "os"
    "pftest/pf"

    "pftest/github.com/golang/protobuf/proto"
)

func write() {
    p1 := &pf.Person{
        Id:   1,
        Name: "小張",
        Phones: []*pf.Phone{
            {pf.PhoneType_HOME, "11111111"},
            {pf.PhoneType_WORK, "22222222"},
        },
    }

    p2 := &pf.Person{
        Id:   2,
        Name: "小王",
        Phones: []*pf.Phone{
            {pf.PhoneType_HOME, "33333333"},
            {pf.PhoneType_WORK, "44444444"},
        },
    }

    p3 := &pf.Person{
        Id:   3,
        Name: "小李",
        Phones: []*pf.Phone{
            {pf.PhoneType_HOME,"55555555"},
            {pf.PhoneType_WORK,"66666666"},
        },
    }

    book := &pf.ContactBook{}
    book.Persons = append(book.Persons, p1)
    book.Persons = append(book.Persons, p2)
    book.Persons = append(book.Persons, p3)

    data, _ := proto.Marshal(book)

    ioutil.WriteFile("./test.txt", data, os.ModePerm)
}

func read() {
    date, _ := ioutil.ReadFile("./test.txt")
    book := &pf.ContactBook{}

    proto.Unmarshal(date, book)
    for _, v := range book.Persons {
        fmt.Println(v.Id, v.Name)
        for _, vv := range v.Phones {
            fmt.Println(vv.Type, vv.Number)
        }
    }
}

func main() {
    write()
    read()
}

 

運行結果如下:

 

四、參考資料

Protobuf簡介和使用

[轉]Protobuf3 語法指南_鳥窩

Golang版protobuf的安裝與使用

 

五、小結

如果有興趣想了解數據的操作,壓縮的全過程,可以考慮使用Protobuf。

它就像一個代碼轉換器,你只需寫好底層協議,然后用Protobuf現成的工具生成對應語言的源文件,從而達到項目中使用相同協議格式進行數據傳輸的目的。

這是我在工作中學習到的一個新技巧!

 

 


免責聲明!

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



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