Protobuf是Google旗下的一款平台无关,语言无关,可扩展的序列化结构数据格式。所以很适合用做数据存储和作为不同应用,不同语言之间相互通信的数据交换格式,只要实现相同的协议格式即同一proto文件被编译成不同的语言版本,加入到各自的工程中去,这样不同语言就可以解析其他语言通过Protobuf序列化的数据。目前官网提供了C++,Python,JAVA,GO等语言的支持。
注:本文主要注重protobuf的使用,所以省去了下载、安装的操作步骤。
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
注意 包名要和文件夹名一致。
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。
它就像一个代码转换器,你只需写好底层协议,然后用Protobuf现成的工具生成对应语言的源文件,从而达到项目中使用相同协议格式进行数据传输的目的。
这是我在工作中学习到的一个新技巧!