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
- 文件定义test.proto:
[plain] view plain copy
- message student
- required string name = 1; //姓名
- required int32 age = 2; //年龄
- optional string addr = 3;
- //班级
- message class
- required string name = 1; //班级名称
- repeated student member = 2; //班级成员
protoc --cpp_out=.test.proto 可以生成test.pb.htest.pb.cc这两个文件
在写程序运行之前,我们直观的看一下protobuf的TextFormat格式是什么样子的吧:
[plain] view plain copy
- name: "Communication 2004"
- member
- name: "flyan338"
- age: 26
- addr: "china"
- member
- name: "likeliu"
- age: 25
- addr: "china"
- member
- name: "gaoy"
- age: 24
- addr: "American"
这份配置表明:一个叫做 "Communication 2004"的班级,有3个student,你可以直接用protobuf来load出来
这份文件怎么生成的呢?代码如下:
[cpp] view plain copy- #include <test.pb.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <iostream>
- #include <fcntl.h>
- #include <fstream>
- #include <cstdio>
- #include <google/protobuf/text_format.h>
- #include <google/protobuf/io/zero_copy_stream_impl.h>
- using namespace std;
- int main(int argc, char** argv)
- if (argc <2)
- printf("programe savefile\\n");
- exit(1);
- //声明一个class结构
- classes c;
- c.set_name("Communication 2004");
- //添加学生
- student* t = c.add_member();
- t->set_name("flyan338");
- t->set_age(26);
- t->set_addr("china");
- t = c.add_member();
- t->set_name("likeliu");
- t->set_age(25);
- t->set_addr("china");
- t = c.add_member();
- t->set_name("gaoy");
- t->set_age(24);
- t->set_addr("American");
- //首先将protobuf输出到一个string中
- std::string p;
- google::protobuf::TextFormat::PrintToString(c,&p);
- //输出到文件中
- ofstream fout;
- fout.open(argv[1], ios::out| ios_base::ate);
- if (!fout.is_open())
- fprintf(stderr, "open %s fail\\n", argv[1]);
- return -1;
- fout <<p<<endl;
- fout.flush();
- fout.close();
- return 0;
只是简单的进行一些set操作,就可以生成这样的配置文件
解析的代码更简单:
[cpp] view plain copy- #include <test.pb.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <iostream>
- #include <fcntl.h>
- #include <fstream>
- #include <cstdio>
- #include <google/protobuf/text_format.h>
- #include <google/protobuf/io/zero_copy_stream_impl.h>
- using namespace std;
- int main(int argc, char** argv)
- if (argc <2)
- printf("programe reloadfile\\n");
- exit(1);
- classes c;
- int fileDescriptor = open(argv[1], O_RDONLY);
- if( fileDescriptor < 0 )
- return -1;
- google::protobuf::io::FileInputStream fileInput(fileDescriptor);
- fileInput.SetCloseOnDelete( true );
- if (!google::protobuf::TextFormat::Parse(&fileInput, &c))
- return -2;
- cout<<"classes name:" <<c.name() <<endl;
- cout<<"student number:"<<c.member_size()<<endl;
- 长文干货 | 如何利用Google的protobuf,来实现自己的RPC框架