Golang语言下使用Protocol Buffer教程

代码仓库地址

 一、介绍

Protobuf是Google旗下的一款平台无关,语言无关,可扩展的序列化结构数据格式。所以很适合用做数据存储和作为不同应用,不同语言之间相互通信的数据交换格式,只要实现相同的协议格式即同一proto文件被编译成不同的语言版本,加入到各自的工程中去,这样不同语言就可以解析其他语言通过Protobuf序列化的数据。目前官网提供了C++,Python,JAVA,GO等语言的支持。

相对于JSON和XML具有以下优点:

  • 简洁
  • 体积小:消息大小只需要XML的1/10 ~ 1⁄3
  • 速度快:解析速度比XML快20 ~ 100倍
  • 使用Protobuf的编译器,可以生成更容易在编程中使用的数据访问代码
  • 更好的兼容性,Protobuf设计的一个原则就是要能够很好的支持向下或向上兼容

注:本文主要注重protobuf的使用,所以省去了下载、安装的操作步骤。

二、创建一个test.proto文件并生成test.pb.go文件

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

注意 包名要和文件夹名一致。

三、在Go语言中使用Protobuf

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

运行结果如下:

四、参考资料

Google proto2 guide

Google proto3 guide

golang 使用 protobuf 的教程

Protobuf简介和使用

[转]Protobuf3 语法指南_鸟窝

Golang版protobuf的安装与使用

五、小结

如果有兴趣想了解数据的操作,压缩的全过程,可以考虑使用Protobuf。

它就像一个代码转换器,你只需写好底层协议,然后用Protobuf现成的工具生成对应语言的源文件,从而达到项目中使用相同协议格式进行数据传输的目的。

这是我在工作中学习到的一个新技巧!

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Spark生态圈

[spark] Standalone模式下Master、WorKer启动流程

而Standalone 作为spark自带cluster manager,需要启动Master和Worker守护进程,本文将从源码角度解析两者的启动流程。Mas...

2282
来自专栏ASP.NET MVC5 后台权限管理系统

ASP.NET MVC5+EF6+EasyUI 后台管理系统(64)-补充WebApi与Unity注入-配置文件

上一篇演示了WebApi利用Unity注入 很多人问我如何用配置文件来配置注入,本节演示如何利用配置文件来注入,道理是一样的,跳转到上一节下载源码一起来动手...

2036
来自专栏一个爱瞎折腾的程序猿

asp.net core使用Swashbuckle.AspNetCore(swagger)生成接口文档

开局一张图,然后开始编,一些基本的asp.net core东西就不再赘述,本文只对Swashbuckle.AspNetCore的几个使用要点进行描述。

1361
来自专栏c#开发者

Asp.net Webform 使用Repository模式实现CRUD操作代码生成工具

Asp.net Webform 使用Repository模式实现CRUD操作代码生成工具 介绍 该工具是通过一个github上的开源项目修改的原始作者https...

4388
来自专栏桥路_大数据

Python3使用Scrapy快速构建第一款爬虫

3557
来自专栏Python爬虫与算法进阶

Hi,这里是我的爬虫笔记

平时有个习惯,会把自己的笔记写在有道云里面,现在做个整理。会长期更新,因为我是BUG制造机。 解析 xpath提取所有节点文本 <div id="test3"...

3495
来自专栏惨绿少年

磁盘管理 之 parted命令添加swap,文件系统

第1章 磁盘管理 1.1 必须要了解的。 1.1.1 ps aux 命令中 RSS 与VSZ的含义 rss 进程占用的物理内存的大小 单位:kb ;   ...

2590
来自专栏java 成神之路

java中设置网络代理

9756
来自专栏程序员的碎碎念

JS动态加载以及JavaScript void(0)的爬虫解决方案

对于使用JS动态加载, 或者将下一页地址隐藏为JavaScript void(0)的网站, 如何爬取我们要的信息呢?

1576
来自专栏有趣的django

python爬虫人门(10)Scrapy框架之Downloader Middlewares

设置下载中间件(Downloader Middlewares)  下载中间件是处于引擎(crawler.engine)和下载器(crawler.engine.d...

3718

扫码关注云+社区