首页 > 其他分享 >配置文件的读取

配置文件的读取

时间:2022-12-10 20:25:15浏览次数:38  
标签:return 读取 配置文件 pos CConfig char linebuf confitem

1. 配置文件(nginx.conf)

 1 #是注释行,
 2 #每个有效配置项用 等号 处理,等号前不超过40个字符,等号后不超过400个字符;
 3 
 4  
 5 #[开头的表示组信息,也等价于注释行
 6 #[Socket]
 7 #ListenPort = 5678    
 8 #DBInfo = 127.0.0.1;1234;myr;123456;mxdb_g
 9 
10 #日志相关
11 [Log]
12 #日志文件输出目录和文件名
13 #Log=logs/error.log
14 Log=error.log
15 
16 #只打印日志等级<= 数字 的日志到日志文件中 ,日志等级0-8,0级别最高,8级别最低。
17 LogLevel = 8
18 
19 #进程相关
20 [Proc]
21 #创建 这些个 worker进程
22 WorkerProcesses = 4
23 
24 #是否按守护进程方式运行,1:按守护进程方式运行,0:不按守护进程方式运行
25 Daemon = 1
26 
27 #处理接收到的消息的线程池中线程数量,不建议超过300
28 ProcMsgRecvWorkThreadCount = 120
29 
30 #和网络相关
31 [Net]
32 #监听的端口数量,一般都是1个,当然如果支持多于一个也是可以的
33 ListenPortCount = 1
34 #ListenPort+数字【数字从0开始】,这种ListenPort开头的项有几个,取决于ListenPortCount的数量,
35 ListenPort0 = 80
36 #ListenPort1 = 443
37 
38 #epoll连接的最大数【是每个worker进程允许连接的客户端数】,实际其中有一些连接要被监听socket使用,实际允许的客户端连接数会比这个数小一些
39 worker_connections = 2048
40 
41 #Sock_RecyConnectionWaitTime:为确保系统稳定socket关闭后资源不会立即收回,而要等一定的秒数,在这个秒数之后,才进行资源/连接的回收
42 Sock_RecyConnectionWaitTime = 150
43 
44 #Sock_WaitTimeEnable:是否开启踢人时钟,1:开启   0:不开启
45 Sock_WaitTimeEnable = 1
46 #多少秒检测一次是否 心跳超时,只有当Sock_WaitTimeEnable = 1时,本项才有用
47 Sock_MaxWaitTime = 20
48 #当时间到达Sock_MaxWaitTime指定的时间时,直接把客户端踢出去,只有当Sock_WaitTimeEnable = 1时,本项才有用
49 Sock_TimeOutKick = 0
50 
51 #和网络安全相关
52 [NetSecurity]
53 #flood检测
54 #Flood攻击检测是否开启,1:开启   0:不开启
55 Sock_FloodAttackKickEnable = 1
56 #Sock_FloodTimeInterval表示每次收到数据包的时间间隔是100(单位:毫秒)
57 Sock_FloodTimeInterval = 100
58 #Sock_FloodKickCounter表示计算到连续10次,每次100毫秒时间间隔内发包,就算恶意入侵,把他kick出去
59 Sock_FloodKickCounter = 10

2. 头文件(ngx_c_conf.h)

 1 #ifndef NGX_C_CONF_H
 2 #define NGX_C_CONF_H
 3 #include <vector>
 4 #include <stdio.h>
 5 #include <string.h>
 6 //结构定义
 7 typedef struct _CConfItem
 8 {
 9     char ItemName[50];
10     char ItemContent[500];
11 }CConfItem,*LPCConfItem;
12 
13 
14 //类名可以遵照一定的命名规则规范,比如老师这里,第一个字母是C,后续的单词首字母大写
15 class CConfig
16 {
17 //---------------------------------------------------
18 //这段代码老师在《c++从入门到精通》 多线程这章老师提过 单例设计模式,就是如下这些代码,大家即便没学过,也可以现在学
19 private:
20     CConfig();
21 public:
22     ~CConfig();
23 private:
24     static CConfig *m_instance;
25 
26 public:
27     static CConfig* GetInstance()               //采用的是单例模式中的饿汉式
28     {
29         if(m_instance == nullptr)
30         {
31             //锁
32             if(m_instance == nullptr)
33             {
34                 m_instance = new CConfig();
35                 static CGarhuishou cl;
36             }
37             //放锁
38         }
39         return m_instance;
40     }
41     class CGarhuishou  //类中套类,用于释放对象
42     {
43     public:
44         ~CGarhuishou()
45         {
46             if (CConfig::m_instance)
47             {
48                 delete CConfig::m_instance;
49                 CConfig::m_instance = nullptr;
50             }
51         }
52     };
53 //---------------------------------------------------
54 public:
55     bool Load(const char *pconfName); //装载配置文件
56     const char *GetString(const char *p_itemname);
57     int  GetIntDefault(const char *p_itemname,const int def);
58 
59 public:
60     std::vector<LPCConfItem> m_ConfigItemList; //存储配置信息的列表
61 };
62 
63 #endif // NGX_C_CONF_H

3. 源文件(ngx_c_conf.cpp)

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <string.h>
  4 #include <vector>
  5 
  6 //自定义头文件放下边,因为g++中用了-I参数,所以这里用<>也可以
  7 #include "ngx_c_conf.h"   //和配置文件处理相关的类,名字带c_表示和类有关
  8 
  9 //截取字符串尾部空格
 10 void Rtrim(char *string)
 11 {
 12     size_t len = 0;
 13     if(string == NULL)
 14         return;
 15 
 16     len = strlen(string);
 17     while(len > 0 && string[len-1] == ' ')   //位置换一下
 18         string[--len] = 0;
 19     return;
 20 }
 21 
 22 //截取字符串首部空格
 23 void Ltrim(char *string)
 24 {
 25     size_t len = 0;
 26     len = strlen(string);
 27     char *p_tmp = string;
 28     if( (*p_tmp) != ' ') //不是以空格开头
 29         return;
 30     //找第一个不为空格的
 31     while((*p_tmp) != '\0')
 32     {
 33         if( (*p_tmp) == ' ')
 34             p_tmp++;
 35         else
 36             break;
 37     }
 38     if((*p_tmp) == '\0') //全是空格
 39     {
 40         *string = '\0';
 41         return;
 42     }
 43     char *p_tmp2 = string;
 44     while((*p_tmp) != '\0')
 45     {
 46         (*p_tmp2) = (*p_tmp);
 47         p_tmp++;
 48         p_tmp2++;
 49     }
 50     (*p_tmp2) = '\0';
 51     return;
 52 }
 53 
 54 
 55 
 56 //静态成员赋值
 57 CConfig *CConfig::m_instance = NULL;
 58 
 59 //构造函数
 60 CConfig::CConfig()
 61 {
 62 }
 63 
 64 //析构函数
 65 CConfig::~CConfig()
 66 {
 67     std::vector<LPCConfItem>::iterator pos;
 68     for(pos = m_ConfigItemList.begin(); pos != m_ConfigItemList.end(); ++pos)
 69     {
 70         delete (*pos);
 71     }//end for
 72     m_ConfigItemList.clear();
 73     return;
 74 }
 75 
 76 //装载配置文件
 77 bool CConfig::Load(const char *pconfName)
 78 {
 79     FILE *fp;
 80     fp = fopen(pconfName,"r");
 81     if(fp == NULL)
 82         return false;
 83 
 84     //每一行配置文件读出来都放这里
 85     char  linebuf[501];   //每行配置都不要太长,保持<500字符内,防止出现问题
 86 
 87     //走到这里,文件打开成功
 88     while(!feof(fp))  //检查文件是否结束 ,没有结束则条件成立
 89     {
 90         //大家要注意老师的写法,注意写法的严密性,商业代码,就是要首先确保代码的严密性
 91         if(fgets(linebuf,500,fp) == NULL) //从文件中读数据,每次读一行,一行最多不要超过500个字符
 92             continue;
 93 
 94         if(linebuf[0] == 0)
 95             continue;
 96 
 97         //处理注释行
 98         if(*linebuf==';' || *linebuf==' ' || *linebuf=='#' || *linebuf=='\t'|| *linebuf=='\n')
 99             continue;
100 
101     lblprocstring:
102         //屁股后边若有换行,回车,空格等都截取掉
103         if(strlen(linebuf) > 0)   //strlen不算\0
104         {   //看看末尾的字符是什么    10代表换行符,13代表回车键,32代表空格
105             if(linebuf[strlen(linebuf)-1] == 10 || linebuf[strlen(linebuf)-1] == 13 || linebuf[strlen(linebuf)-1] == 32)
106             {
107                 linebuf[strlen(linebuf)-1] = 0;
108                 goto lblprocstring;
109             }
110         }
111 
112         if(linebuf[0] == 0)
113             continue;
114         if(*linebuf=='[') //[开头的也不处理
115             continue;
116 
117         //这种 “ListenPort = 5678”走下来;
118         char *ptmp = strchr(linebuf,'=');  //strchr搜索第一次出现字符=的位置
119         if(ptmp != NULL)
120         {
121             LPCConfItem p_confitem = new CConfItem;                    //注意前边类型带LP,后边new这里的类型不带
122             memset(p_confitem,0,sizeof(CConfItem));
123             strncpy(p_confitem->ItemName,linebuf,(int)(ptmp-linebuf)); //等号左侧的拷贝到p_confitem->ItemName
124             strcpy(p_confitem->ItemContent,ptmp+1);                    //等号右侧的拷贝到p_confitem->ItemContent
125 
126             Rtrim(p_confitem->ItemName);
127             Ltrim(p_confitem->ItemName);
128             Rtrim(p_confitem->ItemContent);
129             Ltrim(p_confitem->ItemContent);
130 
131             //printf("itemname=%s | itemcontent=%s\n",p_confitem->ItemName,p_confitem->ItemContent);
132             m_ConfigItemList.push_back(p_confitem);  //内存要释放,因为这里是new出来的
133         } //end if
134     } //end while(!feof(fp))
135 
136     fclose(fp); //这步不可忘记
137     return true;
138 }
139 
140 //根据ItemName获取配置信息字符串,不修改不用互斥
141 const char *CConfig::GetString(const char *p_itemname)
142 {
143     std::vector<LPCConfItem>::iterator pos;
144     for(pos = m_ConfigItemList.begin(); pos != m_ConfigItemList.end(); ++pos)
145     {
146         if(strcasecmp( (*pos)->ItemName,p_itemname) == 0)
147             return (*pos)->ItemContent;
148     }//end for
149     return NULL;
150 }
151 
152 //根据ItemName获取数字类型配置信息,不修改不用互斥
153 int CConfig::GetIntDefault(const char *p_itemname,const int def)
154 {
155     std::vector<LPCConfItem>::iterator pos;
156     for(pos = m_ConfigItemList.begin(); pos !=m_ConfigItemList.end(); ++pos)
157     {
158         if(strcasecmp( (*pos)->ItemName,p_itemname) == 0)
159             return atoi((*pos)->ItemContent);
160     }//end for
161     return def;
162 }

4. main函数(用来测试)

 1 #include <stdio.h>
 2 #include <ngx_c_conf.h>
 3 
 4 int main()
 5 {
 6 
 7     CConfig *p_config = CConfig::GetInstance(); //单例类
 8   
 9     if(p_config->Load("C:\\Users\\123\\Documents\\build-test-Desktop_Qt_5_9_9_MinGW_32bit-Debug\\debug\\nginx.conf") == false) //把配置文件内容载入到内存
10     {
11         printf("Load configFile failed\n");
12     }
13     else
14     {   //只是简单的测试了一下,如果获取数字型的配置信息可以用这个GetIntDefault(const char *p_itemname,const int def)函数,直接得到数字
15 printf("Load configFile success\n"); 16 printf("log = %s\n",p_config->GetString("Log")); 17 printf("LogLevel = %s\n",p_config->GetString("LogLevel")); 18 printf("WorkerProcesses = %s\n",p_config->GetString("WorkerProcesses")); 19 printf("Daemon = %s\n",p_config->GetString("Daemon")); 20  } 21 return 0; 22 }

标签:return,读取,配置文件,pos,CConfig,char,linebuf,confitem
From: https://www.cnblogs.com/dkhlaojogo/p/16972116.html

相关文章