文章目录
- 配置信息设计
- 配置文件加载
- cloud.conf配置文件
- 单例模式的使用
- ReadConfigFile —— 读取配置文件
- GetInstance —— 创建对象
- 其他函数的实现
- 具体实现
- cloud.conf
- config.hpp
配置信息设计
使用文件配置加载一些程序运行的关键信息 可以让程序的运行更加灵活
配置信息:
1.热点判断时间(多长时间没有访问算是非热点文件)
2.文件下载URL前缀路径 (用于表示客户端请求是一个下载请求)
3.压缩包后缀名称 (文件原名称之后 加上后缀 “.lz”)
4.上传文件存放路径 (决定了文件上传之后实际存储在服务器哪里)
5.压缩文件存放路径(决定非热点文件压缩后存放的路径)
6.服务端备份信息存放文件(服务端所记录的备份文件信息的持久化存储处)
7.服务器的监听IP地址 (当程序要运行在其他主机上,则不需要修改程序)
8.服务器的监听端口
配置文件加载
cloud.conf配置文件
创建 cloud.conf 配置文件
单例模式的使用
因为要设计单例中的懒汉模式,所以需要将构造函数私有化
同时为了保证每次获取都是同一个对象,所以定义一个静态的类类型的指针 _instance
需在类外将静态指针初始化
由于多线程下存在线程安全的问题,所以 定义一个静态锁 ,用于保护函数中的实例对象
而锁在类外初始化时不需要给值
_hot_time ——表示热点判断时间
_server_port ——表示 服务器的监听端口
_download_prefix ——表示 下载的url前缀路径
_packfile_suffix ——表示 压缩包后缀名称
_back_dir ——表示备份文件存放目录
_pack_dir ——表示压缩包存放目录
_server_ip ——表示服务器IP地址
_backup_file —— 表示数据信息存放文件
ReadConfigFile —— 读取配置文件
将 上述 配置文件 cloud.conf 看作一个 宏 CONFIG_FILE
使用 之前实现过的文件类 FileUtil 实例化一个对象 fu
创建一个 字符串 body
通过 FileUtil 类中的 GetContent 函数
将cloud.conf 文件数据 放入 body 中
若读取失败,则返回 false
使用之前实现过的 Json类(包含序列化和反序列化功能) 实例化一个对象 root
通过Json类 的 UnSerialize 函数实现反序列化 即将body中的数据 放入 root中
root[“hot_time”].asInt() 表示 获取到 root_time 对应数据中的string数据
所以使用 asString 表示 获取对应的string数据
root[“server_port”].asInt() 表示 获取到 server_port 对应数据中的int数据
所以使用 asInt 表示 获取对应的int数据
GetInstance —— 创建对象
若只是单纯加锁解锁,当两个线程t1 t2同时进入if循环中
当线程t1 new后解锁,线程t2获取锁,继续new,就会造成覆盖 丢失数据
所以采用 双检查加锁 的方式,来解决这一问题
其他函数的实现
在配置文件 函数中 已经将 各个 私有的成员变量 进行赋值
所以在这些函数中 只需返回对应的私有成员变量即可
具体实现
cloud.conf
{
"hot_time": 30,
"server_port":9090,
"server_ip":"192.144.206.100",
"download_prefix":"/download/",
"packfile_suffix":".lz",
"pack_dir": "./packdir/",
"back_dir": "./backdir/",
"backup_file":"./cloud.dat"
}
config.hpp
//防止头文件被重复包含
#ifndef _MY_CONFIG_
#define _MY_CONFIG_
#include"util.hpp"
#include<mutex>
namespace cloud
{
#define CONFIG_FILE "./cloud.conf"
class Config
{
private:
Config()
{
ReadConfigFile();//读取配置文件信息
}
static Config* _instance;
static std::mutex _mutex;
private:
int _hot_time; //热点判断时间
int _server_port; //服务器的监听端口
std::string _server_ip; //下载的url前缀路径
std::string _download_prefix; // 压缩包后缀名称
std::string _packfile_suffix; //备份文件存放目录
std::string _pack_dir; // 压缩包存放目录
std::string _back_dir; // 服务器IP地址
std::string _backup_file; // 数据信息存放文件
bool ReadConfigFile()//读取配置文件
{
FileUtil fu(CONFIG_FILE);
std::string body;
//获取文件内容到body中
if(fu.GetContent(&body) ==false)//读取失败
{
std::cout<<"load config file failed"<<std::endl;
return false;
}
Json::Value root;
if(JsonUtil::UnSerialize(body,&root)==false)//反序列化 字符串转化为结构化数据
{
std::cout<<"parse config file failed"<<std::endl;
return false;
}
_hot_time=root["hot_time"].asInt();
_server_port=root["server_port"].asInt();
_server_ip=root["server_ip"].asString();
_download_prefix=root["download_prefix"].asString();
_packfile_suffix=root["packfile_suffix"].asString();
_pack_dir =root["pack_dir"].asString();
_back_dir =root["back_dir"].asString();
_backup_file=root["backup_file"].asString();
return true;
}
public:
static Config *GetInstance() //创建对象
{
if(_instance==NULL)
{
_mutex.lock();//加锁
//若指针为空 则创建对象
if(_instance==NULL)
{
_instance= new Config();//实例化对象
}
_mutex.unlock();
}
return _instance;
}
int GetHotTime()//获取热点时间
{
return _hot_time;
}
int GetServerPort() //端口号
{
return _server_port;
}
std::string GetServerIp() //IP地址
{
return _server_ip;
}
std::string GetDownloadPrefix()//URL前缀路径
{
return _download_prefix;
}
std::string GetPackFileSuffix()//压缩包后缀名称
{
return _packfile_suffix;
}
std::string GetPackDir() //压缩包存放路径
{
return _pack_dir;
}
std::string GetBackDir()//备份文件存放目录
{
return _back_dir;
}
std::string GetBackupFile()//数据信息存放文件
{
return _backup_file;
}
};
Config* Config::_instance=NULL;
std::mutex Config::_mutex;
}
#endif