当前位置: 首页 > news >正文

项目日记 -云备份 -服务端配置信息模块

博客主页:【夜泉_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"
}

简单解释一下:

KV
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 出来,
同时,deleteCopying 函数,
防止有人乱搞。

宏定义:
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;
}

在这里插入图片描述

补充

3-25加:
既然你配置文件类是第一个知道备份目录和压缩目录等信息的,
那这些文件的初始化就交给你了:
Config()

Config() 
{
    std::cout << "readConfigFile..." << std::endl;
    readConfigFile(); 
    std::cout << "check..." << std::endl;
    check(); // 读了配置信息才能检查,不然你连要检查什么都不知道
}

check()

void check()
{
    std::cout << "checkDir..." << std::endl;
    checkDir();
    std::cout << "checkBackupFile..." << std::endl;
    checkBackupFile();
}

checkDir()

void checkDir()
{
    FileUtils d1 = FileUtils(_backDir);
    if (!d1.exists())
        d1.createDirectory();
    FileUtils d2 = FileUtils(_packDir);
    if (!d2.exists())
        d2.createDirectory();
}

checkBackupFile()

void checkBackupFile()
{
    if(!FileUtils(_backupFile).exists())
        FileUtils(_backupFile).setContent("");
}

在这里插入图片描述

运行前后:
在这里插入图片描述

在这里插入图片描述


希望本篇文章对你有所帮助!并激发你进一步探索编程的兴趣!
本人仅是个C语言初学者,如果你有任何疑问或建议,欢迎随时留言讨论!让我们一起学习,共同进步!

相关文章:

  • 深入解析 Python 正则表达式:全面指南与实战示例
  • Python实现小红书app版爬虫
  • CSS圣杯布局与双飞翼布局
  • WordPress超级菜单插件UberMenu v3.78汉化版
  • NVIDIA TensorRT-LLM:高性能大语言模型推理框架详解
  • AI与.NET技术实操系列(一):开篇
  • CentOS 7 更换 yum 源(阿里云)+ 扩展 epel 源
  • vue3,element-plus 表格单选、多选、反选、全选
  • [深度学习]图像分类项目-食物分类
  • QuecPython 网络协议之TCP/UDP协议最祥解析
  • 实战经验:Gone 框架模块化改造中的 go work 反思
  • 10分钟打造专属AI助手!ToDesk云电脑/顺网云/海马云操作DeepSeek哪家强?
  • 信奥赛CSP-J复赛集训(模拟算法专题)(31):P2692 覆盖
  • 部署Jenkins
  • 提升通信清晰度:通过PoE交换机端口配置语音VLAN
  • CentOS 8.2 上安装 JDK 17 和 Nginx
  • 关于大模型中的Token概念小记
  • 滑动窗口:解决连续区间问题的黄金模板(练习笔记)
  • Elasticsearch:设置向量搜索
  • CentOS安装sshpass工具-自动化SSH密码认证
  • 李勇已任内蒙古乌兰察布市委副书记,曾在中央编办任职
  • 因高颜值走红的女通缉犯出狱后当主播自称“改邪归正”,账号已被封
  • 第152次中老缅泰湄公河联合巡逻执法行动圆满结束
  • 经济日报刊文:积极应对稳住外贸基本盘
  • 温氏股份一季度归母净利润20.01亿元,同比扭亏为盈
  • “五一”假期前多地规范旅游市场:要求明码标价,禁止强迫购物