寫在前面
protobuf是Google開發的一種資料描述語言 (Data Description Language),能夠將結構化的資料序列化,可用於資料存放區,通訊協定等方面,官方版本支援 Go, C++, Java, Python,社區版本支援更多語言.
相對於JSON和XML具有以下優點:
體積小: 訊息大小隻需要XML的1/10 ~ 1⁄3
速度快: 解析速度比XML快20 ~ 100倍
整合度高: 使用Protobuf的編譯器,可以產生更容易在編程中使用的資料存取碼
更好的相容性: Protobuf設計的一個原則就是要能夠很好地向下或向上相容
安裝
1.從 https://github.com/google/protobuf/releases 擷取 Protobuf 編譯器 protoc
wget https://github.com/google/protobuf/releases/download/v3.6.1/protobuf-all-3.6.1.tar.gz tar zxvf protobuf-all-3.6.1.tar.gzcd protobuf-3.6.1./configuremakemake installprotoc -hprotoc --version
遇到的問題及解決方案
[1] libprotoc.so.17: cannot open shared object file: No such file or directory
bjlvxin:~/下載/protobuf-3.6.1$ protoc --versionprotoc: error while loading shared libraries: libprotoc.so.17: cannot open shared object file: No such file or directory解決方案:執行:export LD_LIBRARY_PATH=/usr/local/libbjlvxin:~/下載/protobuf-3.6.1$ export LD_LIBRARY_PATH=/usr/local/lib/ bjlvxin:~/下載/protobuf-3.6.1$ protoc --versionlibprotoc 3.6.1
2.擷取 goprotobuf 提供的 Protobuf 外掛程式 protoc-gen-go(被放置於 $GOPATH/bin 下,$GOPATH/bin 應該被加入 PATH 環境變數,以便 protoc 能夠找到 protoc-gen-go)
此外掛程式被 protoc 使用,用於編譯 .proto 檔案為 Golang 源檔案,通過此源檔案可以使用定義在 .proto 檔案中的訊息。
go get github.com/golang/protobuf/protoc-gen-gocd $GOPATH/src/github.com/golang/protobuf/protoc-gen-gogo buildgo installvi ~/.bashrc 將$GOPATH/bin 加入環境變數:export PATH=$PATH:$GOPATH/binsource ~/.bashrc
3.擷取 goprotobuf 提供的支援庫,包含諸如編碼(marshaling)、解碼(unmarshaling)等功能
go get github.com/golang/protobuf/protocd $GOPATH/src/github.com/golang/protobuf/protogo buildgo install
使用
本文通過golang對protobuf進行使用。
1.通過GoLand建立一個新的golang工程:
2.在 example 包中編寫 person.proto
syntax = "proto3";package example;// person 會產生 Person 命名的結構體message person { int32 id = 1; string name = 2;}// all_person 會按照駝峰規則自動產生名為AllPerson 的結構體message all_person { repeated person Per = 1;}
3.進入 protobuf-golang 工程的 proto 目錄,使用 protoc 編譯 person.proto
protoc --go_out=. person.proto
執行完畢後會在proto目錄下產生對應的go檔案:person.pb.go
4.編寫工程的main.go檔案:
/*Copyright 2018 JD-Tigercreated by lvxin at 18-8-13 下午12:03*/package mainimport ( example "github.com/lvxin1986/protobuf-golang/proto" "log" "github.com/golang/protobuf/proto" "fmt")func main() { // 為 AllPerson 填充資料 //使用protobuf的封裝類型定義 p1 := example.Person{ Id:*proto.Int32(1), Name:*proto.String("lvxin"), } //使用golang的原始類型定義 p2 := example.Person{ Id:2, Name:"gopher", } all_p := example.AllPerson{ Per:[]*example.Person{&p1, &p2}, } // 對資料進行序列化 data, err := proto.Marshal(&all_p) if err != nil { log.Fatalln("Mashal data error:", err) } // 對已經序列化的資料進行還原序列化 var target example.AllPerson err = proto.Unmarshal(data, &target) if err != nil{ log.Fatalln("UnMashal data error:", err) } for k,v := range target.Per { fmt.Println("person[",k,"]:",v.Name) }}
5.開發完畢後直接運行:
6.運行結果如下:
GOROOT=/software/servers/go1.10.3 #gosetupGOPATH=/sourcecode/go/work #gosetup/software/servers/go1.10.3/bin/go build -i -o /tmp/___go_build_main_go /sourcecode/go/work/src/github.com/lvxin1986/protobuf-golang/main.go #gosetup/tmp/___go_build_main_go #gosetupperson[ 0 ]: lvxinperson[ 1 ]: gopherProcess finished with exit code 0
打完收工。
參考文獻
https://www.jianshu.com/p/1a3f1c3031b5
https://segmentfault.com/a/1190000010477733
http://lihaoquan.me/2017/6/29/how-to-use-protobuf.html
https://www.pythonxyz.com/10038-install-protobuf-in-ubuntu.xyz