linux下使用protobuf实现简单配置功能

Posted sunmenggmail

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux下使用protobuf实现简单配置功能相关的知识,希望对你有一定的参考价值。

http://blog.csdn.net/flyan338/article/details/8448518

前言:

    程序一般需要load一些参数列表,一般来说我们可以通过linux自带的命令行解析函数来搞定(getopt_long,如果需要了解的man一 下,manpage里面是有example的),但是对于参数太多,我们不可能写满一屏幕进行传参吧,当然,我们的输入在linux里面也是有限制的。所以呢,一般的做法是load一个配置文件,进行解析;最近在研究了一下protobuf的使用,我们都知道protobuf在网络中作为协议发送比较爽,但是发现用protobuf来实现程序的配置文件管理也是一个 不错的思路。

 

protobuf是何物?

大名鼎鼎的google公司的开源软件,被N多程序员推荐使用,个人认为优点是:

1:api接口很友好,这点很重要

2:serilize之后的包比较小,速度快,这个在网络传输中至关重要

3:可扩展性强,加入和删除字段都是透明的。这个在互联网开发中,经常变更协议的时候十分重要

不过protobuf持久化的东西是一个二进制,基本不可读(可以参考https://developers.google.com/protocol-buffers/docs/overview?hl=zh-CN)

不过最近看到了一个protobuf的接口google::protobuf::TextFormat,发现protobuf支持文本的输出,这样我们就能将protobuf做成一个简单的配置管理库了


[plain]  view plain copy
  1. 文件定义test.proto:  

[plain]  view plain copy
  1. message student  
  2.     required string name = 1;   //姓名  
  3.     required int32  age = 2;    //年龄  
  4.     optional string addr = 3;  
  5.   
  6.   
  7. //班级  
  8. message class  
  9.     required string name = 1;   //班级名称  
  10.     repeated student member = 2;    //班级成员  

protoc --cpp_out=.test.proto  可以生成test.pb.htest.pb.cc这两个文件


在写程序运行之前,我们直观的看一下protobuf的TextFormat格式是什么样子的吧:

[plain]  view plain copy
  1. name: "Communication 2004"  
  2. member   
  3.   name: "flyan338"  
  4.   age: 26  
  5.   addr: "china"  
  6.   
  7. member   
  8.   name: "likeliu"  
  9.   age: 25  
  10.   addr: "china"  
  11.   
  12. member   
  13.   name: "gaoy"  
  14.   age: 24  
  15.   addr: "American"  
  16.   

这份配置表明:一个叫做 "Communication 2004"的班级,有3个student,你可以直接用protobuf来load出来

这份文件怎么生成的呢?代码如下:

[cpp]  view plain copy
  1. #include <test.pb.h>  
  2. #include <stdlib.h>  
  3. #include <stdio.h>  
  4. #include <string.h>  
  5. #include <iostream>  
  6. #include <fcntl.h>  
  7. #include <fstream>  
  8. #include <cstdio>  
  9. #include <google/protobuf/text_format.h>  
  10. #include <google/protobuf/io/zero_copy_stream_impl.h>  
  11.   
  12. using namespace std;  
  13. int main(int argc, char** argv)  
  14.     if (argc <2)  
  15.         printf("programe savefile\\n");  
  16.         exit(1);  
  17.       
  18.   
  19.     //声明一个class结构  
  20.     classes c;  
  21.     c.set_name("Communication 2004");  
  22.     //添加学生  
  23.     student* t = c.add_member();  
  24.     t->set_name("flyan338");  
  25.     t->set_age(26);  
  26.     t->set_addr("china");  
  27.       
  28.     t = c.add_member();  
  29.     t->set_name("likeliu");  
  30.     t->set_age(25);  
  31.     t->set_addr("china");  
  32.    
  33.     t = c.add_member();  
  34.     t->set_name("gaoy");  
  35.     t->set_age(24);  
  36.     t->set_addr("American");  
  37.   
  38.   
  39.     //首先将protobuf输出到一个string中  
  40.     std::string p;  
  41.     google::protobuf::TextFormat::PrintToString(c,&p);  
  42.       
  43.     //输出到文件中  
  44.     ofstream fout;  
  45.     fout.open(argv[1], ios::out| ios_base::ate);  
  46.     if (!fout.is_open())  
  47.         fprintf(stderr, "open %s fail\\n", argv[1]);  
  48.         return -1;  
  49.       
  50.     fout <<p<<endl;  
  51.     fout.flush();  
  52.     fout.close();  
  53.   
  54.     return 0;  
  55.   

只是简单的进行一些set操作,就可以生成这样的配置文件

 

解析的代码更简单:

[cpp]  view plain copy
  1. #include <test.pb.h>  
  2. #include <stdlib.h>  
  3. #include <stdio.h>  
  4. #include <string.h>  
  5. #include <iostream>  
  6. #include <fcntl.h>  
  7. #include <fstream>  
  8. #include <cstdio>  
  9. #include <google/protobuf/text_format.h>  
  10. #include <google/protobuf/io/zero_copy_stream_impl.h>  
  11.   
  12. using namespace std;  
  13. int main(int argc, char** argv)  
  14.     if (argc <2)  
  15.         printf("programe reloadfile\\n");  
  16.         exit(1);  
  17.       
  18.   
  19.     classes c;  
  20.     int fileDescriptor = open(argv[1], O_RDONLY);  
  21.     if( fileDescriptor < 0 )  
  22.         return -1;  
  23.       
  24.     google::protobuf::io::FileInputStream fileInput(fileDescriptor);  
  25.     fileInput.SetCloseOnDelete( true );  
  26.     if (!google::protobuf::TextFormat::Parse(&fileInput, &c))  
  27.         return -2;  
  28.       
  29.     cout<<"classes name:" <<c.name() <<endl;  
  30.     cout<<"student number:"<<c.member_size()<<endl;  
  31. 长文干货 | 如何利用Google的protobuf,来实现自己的RPC框架

    用于非 protobuf 类的 protobuf `oneof` 功能的 C++ 实现

    linux下protobuf-c的安装

    Centos6.5下安装protobuf及简单使用

    Linux下使用acme.sh 配置https 免费证书

    linux下安装protobuf