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

生命不止,继续 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())
}

Go实战--go中使用google/protobuf(The way to go)_第1张图片

你可能感兴趣的:(go,Go从不放弃到实战)