您的位置:首页 > 编程语言 > Go语言

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

2017-05-18 17:39 1486 查看
生命不止,继续 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.proto

It has these top-level messages:
HelloWorld
*/
package goprotobuf

import 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.Marshal
var _ = fmt.Errorf
var _ = 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 package

type 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 main

import 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 main

import 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())
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: