项目日记 -云备份 -服务器配置信息模块
博客主页:【夜泉_ly】
本文专栏:【项目日记-云备份】
欢迎点赞👍收藏⭐关注❤️
代码已上传 gitee
目录
- 前言
- 配置信息文件
- 文件配置类
- getInstance 获得实例
- readConfigFile 读取配置信息文件
- 测试
前言
在之前的文章中,
我已经实现了服务端的实用工具类,
本篇。。
等等,先说一下,
我将之前工具类的成员函数名全改了,
从首字母大写变成了首字母小写,
至于原因。。。这样更顺眼一些?
本篇将实现服务器配置信息模块,
由一个配置信息文件,
和一个文件配置类组成。
配置信息文件
开始前,我们必须知道,
为什么我们需要这个模块?
或者说,为什么我们需要配置信息文件?
举个简单的例子——服务器 ip
地址,
如果无配置信息文件,
当程序想跑在不同服务器上时,
还得手动去改代码中的赋值;
当我们将服务器 ip
地址写入配置信息文件,
那么程序启动时只需读取这个文件,
我们想修改 ip
地址也只用改这个文件。
所以,配置信息文件必须要有:
CloudBackup/src/config.conf
{
"hot_time" : 10,
"server_port" : 8899,
"server_ip" : "113.44.51.126",
"download_prefix" : "/download/",
"packfile_suffix" : ".lz",
"pack_dir" : "./packdir/",
"back_dir" : "./backdir/",
"backup_file" : "./cloud.dat"
}
简单解释一下:
K | V |
---|---|
hot_time | 多长时间没访问算热文件(测试时可以设短一点,比如10秒) |
server_port | 服务端的端口号 |
server_ip | 服务器的ip地址 |
download_prefix | 如果客户端传来的url带这个前缀,说明他要下载文件 |
packfile_suffix | 压缩包的后缀名(毕竟压缩格式可能会变) |
pack_dir | 放备份文件的目录 |
back_dir | 放已经被压缩的非热点文件的目录 |
backup_file | 存放所有备份文件的信息,的文件 |
如果你是第一次看,可能会很懵,
不过没关系,之后用多了就不会懵了。
文件配置类
接下来,为了更好的管理这些数据,
需要写个文件配置类,大概长这样:
CloudBackup/src/config.conf
#pragma once
#include "utils.hpp"
#include <mutex>
namespace Cloud {
#define CONFIG_FILE_PATH "./config.conf"
class Config {
public:
static Config* getInstance();
const size_t getHotTime() const { return _hotTime; }
const size_t getServerPort() const { return _serverPort; }
const std::string& getServerIp() const { return _serverIp; }
const std::string& getDownloadPrefix() const { return _downloadPrefix; }
const std::string& getPackfileSuffix() const { return _packfileSuffix; }
const std::string& getPackDir() const { return _packDir; }
const std::string& getBackDir() const { return _backDir; }
const std::string& getBackupFile() const { return _backupFile; }
void updata() { readConfigFile(); }
void show() const ;
private:
Config() { readConfigFile(); }
Config(const Config&) = delete;
Config operator=(const Config&) = delete;
void readConfigFile();
private:
size_t _hotTime;
size_t _serverPort;
std::string _serverIp;
std::string _downloadPrefix;
std::string _packfileSuffix;
std::string _packDir;
std::string _backDir;
std::string _backupFile;
private:
static Config* _instance;
static std::mutex _mutex;
};
std::mutex Config::_mutex;
Config* Config::_instance = nullptr;
} // namespace Cloud
想必你已经看出来了,这是个单例类,
(毕竟配置信息只可能有一份),
用的是懒汉模式,
即需要的时候再 new
出来,
同时,delete
掉 Copying
函数,
防止有人乱搞。
宏定义:
CONFIG_FILE_PATH
配置信息文件的路径(这个只能手写,没办法)
成员函数:
getInstance
获得实例
getXXX
获得XXX
update
更新配置信息(万一想在服务器运行时改配置信息呢?所以写了这个)
show
展示配置信息(这个是用来测试的,可以删)
readConfigFile
读取配置信息文件
成员变量:
一堆配置信息,
一个指针,
一把锁。
getInstance 获得实例
static Config *getInstance()
{
if (_instance == nullptr)
{
_mutex.lock();
if (_instance == nullptr)
_instance = new Config();
_mutex.unlock();
}
return _instance;
}
双 if
,
第一个if
防止明明有实例了,
还要加锁再判断;
第二个if
防止多个线程挤在lock
处,
之后拿到锁后看都不看就new
个新的实例。
readConfigFile 读取配置信息文件
void readConfigFile()
{
std::string config;
if (FileUtils(CONFIG_FILE_PATH).getContent(&config) == false)
{
std::cout << "Read config file error\n";
return;
}
Json::Value root;
JsonUtils::deSerialize(config, &root);
_hotTime = root["hot_time"].asInt64();
_serverPort = root["server_port"].asInt64();
_serverIp = root["server_ip"].asString();
_downloadPrefix = root["download_prefix"].asString();
_packfileSuffix = root["packfile_suffix"].asString();
_packDir = root["pack_dir"].asString();
_backDir = root["back_dir"].asString();
_backupFile = root["backup_file"].asString();
std::cout << "read Config file done\n"; // 可以注释掉
show(); // 可以注释掉
}
最后两行,虽然我说可以注释掉,
但其实还是有点必要的,
万一,
你哪天心血来潮,
想改改配置信息文件,
比如把 "hot_time"
改成了 "hotTime"
,
但你忘记改 readConfigFile
了!
它读的时候是不会报错的,
而是直接把你的 _hotTime
设置为 0。
你应该也不想在各个类里面查了很久的bug,
最后发现是配置信息根本没读上来吧?
show 展示配置信息
void show() const
{
std::cout << "hotTime: " << _hotTime << std::endl;
std::cout << "serverPort: " << _serverPort << std::endl;
std::cout << "serverIp: " << _serverIp << std::endl;
std::cout << "downloadPrefix: " << _downloadPrefix << std::endl;
std::cout << "packfileSuffix: " << _packfileSuffix << std::endl;
std::cout << "packDir: " << _packDir << std::endl;
std::cout << "backDir: " << _backDir << std::endl;
std::cout << "backupFile: " << _backupFile << std::endl;
}
测试
这个模块的测试很简单:
#include "config.hpp"
int main()
{
Cloud::Config::getInstance();
return 0;
}
希望本篇文章对你有所帮助!并激发你进一步探索编程的兴趣!
本人仅是个C语言初学者,如果你有任何疑问或建议,欢迎随时留言讨论!让我们一起学习,共同进步!