我是靠谱客的博主 悦耳牛排,最近开发中收集的这篇文章主要介绍数据格式之protobuf,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

简介

  • 二进制数据交换格式
  • 基于idl语言自动生成对应的数据结构代码

protobuf开发流程

  1. 搭建环境
  2. 编写IDL文件(.proto文件)
  3. 根据IDL文件生成对应语言的数据结构代码
  4. 使用相应的工具包完成序列化和反序列化

环境搭建

  • 安装protoc
    • 下载protoc-3.6.1-osx-x86_64.zip文件并解压
    cd protoc-3.6.1-osx-x86_64
    cp -r include/ /usr/local/include/
    cp -r bin/ /usr/local/bin/
    
  • 安装go工具包
go get -u github.com/golang/protobuf
  • 安装protoc-gen-go
go install google.golang.org/protobuf/cmd/protoc-gen-go

编写IDL文件

  • 数据类型对应表
    在这里插入图片描述
  • IDL编写
    • 枚举类型enum
    enum Demo{
    	Field1 = 0;
    	Field2 = 1;
    }
    
    • map类型
    message Bar {}
    message Baz {
      map<string, Bar> foo = 1;
    }
    
    • 结构体类型message
    message Person {
    	//数字表示表识号 
    	int32 id = 1;
    	string name = 2;
    	//repeated表示可重复
    	repeated Phone phones = 3;
    }
    
    • 完整的一个IDL文件
    //指定版本
    //注意proto3与proto2的写法有些不同
    syntax = "proto3";
     
    //包名,通过protoc生成时go文件时
    package address;
     
    //手机类型
    //枚举类型第一个字段必须为0
    enum PhoneType {
        HOME = 0;
        WORK = 1;
    }
     
    //手机
    message Phone {
        PhoneType type = 1;
        string number = 2;
    }
     
    //人
    message Person {
        //后面的数字表示标识号
        int32 id = 1;
        string name = 2;
        //repeated表示可重复
        //可以有多个手机
        repeated Phone phones = 3;
    }
     
    //联系簿
    message ContactBook {
        repeated Person persons = 1;
    }
    

根据IDL文件生成对应语言的数据结构代码

protoc --proto_path=src --go_out=build/gen --go_opt=paths=source_relative src/address.proto 
  • 解释:--proto_path表示proto文件的搜索路径, --go_out:go文件的输出路径, --go_opt=paths=source_relative:在proto文件相同的路径下生成
  • --go_out的路径需要事先创建好

使用相应的工具包完成序列化和反序列化

package main

import (
	"fmt"
	"io/ioutil"
	"github.com/golang/protobuf/proto"
	"build/gen/address"
)

func writeProto(filename string) (err error) {
	var contactBook address.ContactBook
	for i := 0; i < 64; i++ {
		p := &address.Person{
			Id:   int32(i),
			Name: fmt.Sprintf("陈%d", i),
		}

		phone := &address.Phone{
			Type:   address.PhoneType_HOME,
			Number: "15910624165",
		}

		p.Phones = append(p.Phones, phone)
		contactBook.Persons = append(contactBook.Persons, p)
	}

	data, err := proto.Marshal(&contactBook)
	if err != nil {
		fmt.Printf("marshal proto buf failed, err:%vn", err)
		return
	}

	err = ioutil.WriteFile(filename, data, 0755)
	if err != nil {
		fmt.Printf("write file failed, err:%vn", err)
		return
	}
	return
}

func readProto(filename string) (err error) {
	var contactBook address.ContactBook
	data, err := ioutil.ReadFile(filename)
	if err != nil {
		return
	}
	err = proto.Unmarshal(data, &contactBook)
	if err != nil {
		return
	}

	fmt.Printf("proto:%#vn", contactBook)
	return
}

func main() {
	filename := "contactbook.dat"
	err := writeProto(filename)
	if err != nil {
		fmt.Printf("write proto failed, err:%vn", err)
		return
	}
	err = readProto(filename)
	if err != nil {
		fmt.Printf("read proto failed, err:%vn", err)
		return
	}
}

最后

以上就是悦耳牛排为你收集整理的数据格式之protobuf的全部内容,希望文章能够帮你解决数据格式之protobuf所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(49)

评论列表共有 0 条评论

立即
投稿
返回
顶部