Go实战--go中使用google/protobuf(The way to go)

来源:互联网 发布:郑州淘宝加盟 编辑:程序博客网 时间:2024/04/23 14:57

生命不止,继续 go go go !!!

很久之前写过关于protobuf的博客:
《google/protobuf–VS2015编译、使用》
http://blog.csdn.net/wangshubo1989/article/details/53437190

何为protobuf?

Protocol Buffers (a.k.a., protobuf) are Google’s language-neutral, platform-neutral, extensible mechanism for serializing structured data. You can find protobuf’s documentation on the Google Developers site.

protocolbuffer(以下简称PB)是google 的一种数据交换的格式,它独立于语言,独立于平台。google 提供了多种语言的实现:Java、c#、c++、Go 和 Python,每一种实现都包含了相应语言的编译器以及库文件。由于它是一种二进制的格式,比使用 xml 进行数据交换快许多。可以把它用于分布式应用之间的数据通信或者异构环境下的数据交换。作为一种效率和兼容性都很优秀的二进制数据传输格式,可以用于诸如网络传输、配置文件、数据存储等诸多领域。

安装proto
这里为了方便,在Windows上直接下载release版本,protoc-3.3.0-win32.zip:
https://github.com/google/protobuf/releases/tag/v3.3.0

然后把bin目录加入到环境变量中。

安装Go protocol buffers plugin

go get -u github.com/golang/protobuf/protoc-gen-go

好吧,这里我默认你设置好了go env

新建一个proto文件
新建一个proto文件,命名为test.proto,并键入内容:

package goprotobuf; message HelloWorld {     required int32     id = 1;  // ID     required string    str = 2;  // str     optional int32     opt = 3;  //optional field }

运行protoc命令

protoc --go_out=. test.proto

此时,生成了一个文件,test.pb.go,内容如下:

// Code generated by protoc-gen-go. DO NOT EDIT.// source: test.proto/*Package goprotobuf is a generated protocol buffer package.It is generated from these files:    test.protoIt has these top-level messages:    HelloWorld*/package goprotobufimport proto "github.com/golang/protobuf/proto"import fmt "fmt"import math "math"// Reference imports to suppress errors if they are not otherwise used.var _ = proto.Marshalvar _ = fmt.Errorfvar _ = math.Inf// This is a compile-time assertion to ensure that this generated file// is compatible with the proto package it is being compiled against.// A compilation error at this line likely means your copy of the// proto package needs to be updated.const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto packagetype HelloWorld struct {    Id               *int32  `protobuf:"varint,1,req,name=id" json:"id,omitempty"`    Str              *string `protobuf:"bytes,2,req,name=str" json:"str,omitempty"`    Opt              *int32  `protobuf:"varint,3,opt,name=opt" json:"opt,omitempty"`    XXX_unrecognized []byte  `json:"-"`}func (m *HelloWorld) Reset()                    { *m = HelloWorld{} }func (m *HelloWorld) String() string            { return proto.CompactTextString(m) }func (*HelloWorld) ProtoMessage()               {}func (*HelloWorld) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }func (m *HelloWorld) GetId() int32 {    if m != nil && m.Id != nil {        return *m.Id    }    return 0}func (m *HelloWorld) GetStr() string {    if m != nil && m.Str != nil {        return *m.Str    }    return ""}func (m *HelloWorld) GetOpt() int32 {    if m != nil && m.Opt != nil {        return *m.Opt    }    return 0}func init() {    proto.RegisterType((*HelloWorld)(nil), "goprotobuf.HelloWorld")}func init() { proto.RegisterFile("test.proto", fileDescriptor0) }var fileDescriptor0 = []byte{    // 104 bytes of a gzipped FileDescriptorProto    0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x2a, 0x49, 0x2d, 0x2e,    0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x4a, 0xcf, 0x07, 0x33, 0x92, 0x4a, 0xd3, 0x94,    0x1c, 0xb8, 0xb8, 0x3c, 0x52, 0x73, 0x72, 0xf2, 0xc3, 0xf3, 0x8b, 0x72, 0x52, 0x84, 0xf8, 0xb8,    0x98, 0x32, 0x53, 0x24, 0x18, 0x15, 0x98, 0x34, 0x58, 0x83, 0x98, 0x32, 0x53, 0x84, 0x04, 0xb8,    0x98, 0x8b, 0x4b, 0x8a, 0x24, 0x98, 0x14, 0x98, 0x34, 0x38, 0x83, 0x40, 0x4c, 0x90, 0x48, 0x7e,    0x41, 0x89, 0x04, 0xb3, 0x02, 0xa3, 0x06, 0x6b, 0x10, 0x88, 0x09, 0x08, 0x00, 0x00, 0xff, 0xff,    0x84, 0x25, 0xf6, 0x05, 0x5a, 0x00, 0x00, 0x00,}

protobuf应用
在GOPATH的src的文件夹下新建文件夹go_protobuf,并新建文件main.go
然后在go_protobuf中新建proto文件夹,并把之前生成的test.pb.go放入proto文件夹

写代码了

protobuf写入文件:

package mainimport proto "github.com/golang/protobuf/proto"import (    "fmt"    "os"    "go_protobuf/proto")func main() {    msg := &goprotobuf.HelloWorld{        Id:  proto.Int32(996),        Str: proto.String("fuck"),    }    path := string("./test.txt")    f, err := os.Create(path)    if err != nil {        fmt.Printf("failed: %s\n", err)        return    }    defer f.Close()    buffer, err := proto.Marshal(msg)    f.Write(buffer)}

读取文件到protobuf:

package mainimport proto "github.com/golang/protobuf/proto"import (    "fmt"    "go_protobuf/proto"    "io"    "os")func CheckError(err error) {    if err != nil {        fmt.Println(err.Error())        os.Exit(-1)    }}func main() {    path := string("./test.txt")    file, err := os.Open(path)    if err != nil {        fmt.Printf("failed: %s\n", err)        return    }    defer file.Close()    fi, err := file.Stat()    CheckError(err)    buffer := make([]byte, fi.Size())    _, err = io.ReadFull(file, buffer)    CheckError(err)    msg := &goprotobuf.HelloWorld{}    err = proto.Unmarshal(buffer, msg)    CheckError(err)    fmt.Printf("read: %s\n", msg.String())}

这里写图片描述

原创粉丝点击