简述ProtoBuf

全称:protocol buffers

一种语言无关、平台无关、可扩展的序列化结构数据的方法,它可用于(数据)通信协议、数据存储等

一种灵活、高效,自动化机制的结构数据序列化方法-可类比XML,但是比XML更小(3-10倍)、更快(20-100倍)、更为简单。

体现:

可以定义数据的结构,然后使用特殊生成的源代码轻松地在各种数据流中使用各种语言进行编写和读取结构数据,甚至可以更新数据结构,而不破坏由旧数据结构编译的已部署程序

特点:

  • 语言无关、平台无关。即ProtoBuf支持Java、C++、Python等多种语言,支持多个平台
  • 高效。即比XML更小(3-10倍)、更快(20-100倍)、更为简单
  • 扩展性、兼容性好。可以更新数据结构,而不影响和破坏原有的旧程序

使用:

  • 创建.proto文件,定义数据结构
message xxx {
  // 字段规则:required -> 字段只能也必须出现 1 次
  // 字段规则:optional -> 字段可出现 0 次或1次
  // 字段规则:repeated -> 字段可出现任意多次(包括 0)
  // 类型:int32、int64、sint32、sint64、string、32-bit ....
  // 字段编号:0 ~ 536870911(除去 19000 到 19999 之间的数字)
  字段规则 类型 名称 = 字段编号;
}

示例:

message Example1 {
    optional string stringVal = 1;
    optional bytes bytesVal   = 2;
    message EmbeddedMessage {
        int32 int32Val   = 1;
        string stringVal = 2;
    }

    optional EmbeddedMessage embeddedExample1 = 3;
    repeated int32 repeatedInt32Val = 4;
    repeated string repeatedStringVal = 5;
}
  • protoc编译.proto文件生成读写接口

.proto文件中定义了数据结构,面向开发者和业务程序,并不面向存储和传输。需要进行序列化、反序列化以及读写。

通过protoc编译器实现

命令:

// $SRC_DIR: .proto 所在的源目录
// --cpp_out: 生成 c++ 代码
// $DST_DIR: 生成代码的目标目录
// xxx.proto: 要针对哪个 proto 文件生成接口代码

protoc -I=$SRC_DIR --cpp_out=$DST_DIR $SRC_DIR/xxx.proto

最终生成的代码提供类似如下的接口:

bool SerializeToString(string* output) const;    //将对象序列化为二进制字符串
bool ParseFromString(const string& data);        // 解析一个二进制字符串

bool SerializeToOstream(ostream* output) const;     // 将对象序列化成ostream
bool ParseFromIstream(istream* input);            //解析istream

例子生成的接口:

void clear_int32val();
void set_int32val(::google::protobuf::int32 value)     //设置int32val值
::google::protobuf::int32 int32val() const;            //获取int32val值

void clear_stringval();
void set_stringval(const char* value);                 // 设置stringval值
const ::std::string& stringval() const;                /// 获取stringval值
  • 调用接口实现序列化、反序列化以及读写

测试代码:

//
// Created by yue on 18-7-21.
//
#include <iostream>
#include <fstream>
#include <string>
#include "single_length_delimited_all.pb.h"

int main() {
    Example1 example1;
    example1.set_stringval("hello,world");
    example1.set_bytesval("are you ok?");

    Example1_EmbeddedMessage *embeddedExample2 = new Example1_EmbeddedMessage();

    embeddedExample2->set_int32val(1);
    embeddedExample2->set_stringval("embeddedInfo");
    example1.set_allocated_embeddedexample1(embeddedExample2);

    example1.add_repeatedint32val(2);
    example1.add_repeatedint32val(3);
    example1.add_repeatedstringval("repeated1");
    example1.add_repeatedstringval("repeated2");

    std::string filename = "single_length_delimited_all_example1_val_result";
    std::fstream output(filename, std::ios::out | std::ios::trunc | std::ios::binary);
    if (!example1.SerializeToOstream(&output)) {
        std::cerr << "Failed to write example1." << std::endl;
        exit(-1);
    }

    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

子建莫敌

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值