zoukankan      html  css  js  c++  java
  • ProtoBuffer使用笔记

    ProtoBuffer是由谷歌研发的对象序列化和反序列化的开源工具,ProtoBuffer和Xml类似,都是数据描述工具,后者使用更为广泛,前者Google内部使用且具有更高的效率。该工具安装和使用都很简单,查看了下网上贴代码的居多,这里整理下以便以后使用。

    1.安装

    sudo apt-get install protobuf-compiler

    2.说明文档

    语法说明请参考:

    [1]. Protocol Buffer技术详解(语言规范)

     简单例子请参考:

    [1]. Google Protocol Buffers浅析(一,二,三,四)(windows下的使用,linux用户可参考其语法)

    [2]. ProtoBuf 常用序列化/反序列化API

    3. Eclipse CDT下使用ProtoBuffer

    编写一个用户信息列表的描述,并完成对象序列化和反序列化操作。

    a. 新建项目

    建立一个新的c++ project,命名为TestPbuffer,并建立文件夹src, data, proto:

    b. 数据描述

    在目录proto下添加代码,person.proto,并编辑加入以下代码:

    message Person{
        required string name = 1;
        required int32  age  = 2;
        optional string email = 3;
        enum PhoneType{
            HOME = 1;
            MOBILE = 2;
            WORK = 3;
        }
        message Phone{
            required int64 id = 1;
            optional PhoneType type = 2 [default = HOME];
        }
        repeated Phone phoneNum = 4;
    }
    
    message UserList{
        required string name = 1;
        repeated Person users = 2;
    }

    Proto文件与xml类似,能够对数据进行格式化的描述,以上的数据描述完成了用户信息记录列表的定义。具体含义请参阅:Protocol Buffer技术详解(语言规范)

    c. 生成c++代码

    在控制台下跳转到目录proto,然后执行以下编译命令:

    $ protoc person.proto --cpp_out=../src/

    生成的c++文件person.pb.h和person.pb.cc存放在src下。对象的序列化和反序列化就是通过这两个文件完成操作了。

    d. 配置Include和Link

    右击project的Propertise->C++ Build->Setting,具体配置如下图所示:

    e.编写测试程序

    在src目录下添加TestProtoBuffer.cpp文件,并添加以下代码:

    //============================================================================
    // Name        : TestPbuffer.cpp
    // Author      : xiankai.chen
    // Version     :
    // Copyright   : xiankai.chen@qq.com
    // Description : Test proto buffer in C++, Ansi-style
    //============================================================================
    
    #include <iostream>
    #include <fstream>
    #include <string>
    
    #include "person.pb.h"
    
    using namespace std;
    
    int main() {
        /*write object to file*/
        UserList user_list;
    
        user_list.set_name("用户列表");
        //add person 1
        Person* person;
        Person::Phone *phone;
        person = user_list.add_users();
        person->set_name("cxk");
        person->set_age(30);
        person->set_email("xiankai.chen@qq.com");
        phone = person->add_phonenum();
        phone->set_type(Person::HOME);
        phone->set_id(13418638333);
        phone = person->add_phonenum();
        phone->set_type(Person::MOBILE);
        phone->set_id(13234444555);
    
        //add person 2
        person = user_list.add_users();
        person->set_name("lgm");
        person->set_age(30);
        person->set_email("77015684@gmail.com");
        phone = person->add_phonenum();
        phone->set_type(Person::HOME);
        phone->set_id(13344655445);
        phone = person->add_phonenum();
        phone->set_type(Person::MOBILE);
        phone->set_id(13765546785);
    
        fstream output("./data/myinfo.dat",ios::out|ios::binary);
        user_list.SerializeToOstream(&output);
        output.close();
        output.clear();
    
    
        /*read object from file*/
        fstream input("./data/myinfo.dat",ios::in|ios::binary);
        UserList userlist_in;
        if(!userlist_in.ParseFromIstream(&input))
        {
            cout<<"parse error"<<endl;
            return -1;
        }
        cout<<"userlist name: "<< userlist_in.name() <<endl;
    
        for(int i = 0; i < userlist_in.users_size(); i++)
        {
            cout<<"person["<<i<<"] name:"<< userlist_in.users(i).name()<< endl;
            cout<<"person["<<i<<"]  age:"<< userlist_in.users(i).age()<< endl;
            cout<<"person["<<i<<"]email:"<< userlist_in.users(i).email()<< endl;
            for(int j = 0; j < userlist_in.users(i).phonenum_size(); j++)
            {
                cout<<"person["<<i<<"] phonenum["<<j<<"] type:"<< userlist_in.users(i).phonenum(j).type()<< endl;
                cout<<"person["<<i<<"] phonenum["<<j<<"] no:"<< userlist_in.users(i).phonenum(j).id()<< endl;
            }
        }
        input.close();
        input.clear();
    
        return 0;
    }

    f.执行测试结果

    如下所示

    userlist name: 用户列表
    person[0] name:cxk
    person[0]  age:30
    person[0]email:xiankai.chen@qq.com
    person[0] phonenum[0] type:1
    person[0] phonenum[0] no:13418638333
    person[0] phonenum[1] type:2
    person[0] phonenum[1] no:13234444555
    person[1] name:lgm
    person[1]  age:30
    person[1]email:77015684@gmail.com
    person[1] phonenum[0] type:1
    person[1] phonenum[0] no:13344655445
    person[1] phonenum[1] type:2
    person[1] phonenum[1] no:13765546785

    g. 工程代码

    下载链接:TestPbuffer.tar.gz

  • 相关阅读:
    leetcode 576. Out of Boundary Paths 、688. Knight Probability in Chessboard
    leetcode 129. Sum Root to Leaf Numbers
    leetcode 542. 01 Matrix 、663. Walls and Gates(lintcode) 、773. Sliding Puzzle 、803. Shortest Distance from All Buildings
    leetcode 402. Remove K Digits 、321. Create Maximum Number
    leetcode 139. Word Break 、140. Word Break II
    leetcode 329. Longest Increasing Path in a Matrix
    leetcode 334. Increasing Triplet Subsequence
    leetcode 403. Frog Jump
    android中webView加载H5,JS不能调用问题的解决
    通过nginx中转获取不到IP的问题解决
  • 原文地址:https://www.cnblogs.com/cv-pr/p/6296587.html
Copyright © 2011-2022 走看看