C 项目云备份⑤数据管理模块的设计与实现
终极管理员 知识笔记 125阅读
文章目录 专栏导读1.要管理的数据有哪些2.如何管理数据3.数据信息结构体设计与实现4.数据管理类设计5.数据管理类实现6.数据管理模块整理
专栏导读

作者简介花想云 在读本科生一枚C/C领域新星创作者新星计划导师阿里云专家博主内容合伙人…致力于 C/C、Linux 学习。
专栏简介本文收录于 C项目——云备份

相关专栏推荐C语言初阶系列、C语言进阶系列 、C系列、数据结构与算法、Linux
项目Gitee链接 1.要管理的数据有哪些 文件实际存储路径
当客户要下载文件时则从这个文件中读取数据进行响应文件是否被压缩标志
判断文件是否已经被压缩了压缩包存储路径
如果一个文件是非热点文件则会被压缩这个就是压缩包存储的路径 如果客户端要下载文件则需要先解压缩然后读取解压后的文件数据
还有各类文件属性信息
:
文件大小
文件最后一次修改时间
文件最后一次访问时间
文件访问URL中资源路径path
2.如何管理数据 用于数据信息访问
使用hash
表在内存中管理数据以文件访问URL
为key
数据信息结构
为val
。访问速度快。以文件访问URL
来作为key
是因为客户端浏览器下载文件时总是以URL
作为请求
持久化存储管理
使用JSON序列化
将所有数据保存到文件中
struct BackupInfo
结构中包含要管理的文件各项属性信息NewBackUpInfo
负责将传递进来文件各项属性信息组织起来 typedef struct BackupInfo{ bool pack_flag; // 文件是否被压缩标志 size_t fsize; // 文件大小 time_t mtime; // 文件最后一次修改时间 time_t atime; // 文件最后一次访问时间 std::string real_path; // 文件实际存储路径 std::string pack_path; // 压缩包存储路径 std::string url; // 文件访问URL bool NewBackupInfo(const std::string &realpath) { FileUtil fu(realpath); if(fu.Exists() false) { std::cout << new backupinfo: file not exit << std::endl; return false; } Config* config Config::GetInstance(); std::string packdir config->GetPackDir(); std::string packsuffix config->GetPackFileSuffix(); std::string download_prefix config->GetDownloadPrefix(); pack_flag false; fsize fu.FileSize(); mtime fu.LastMtime(); atime fu.LastATime(); real_path realpath; pack_path packdir fu.FileName() packsuffix; url download_prefix fu.FileName(); return true; }}BackupInfo;
4.数据管理类设计 数据管理类负责将数据信息管理起来。
数据化管理DataManger
中包含以下成员
class DataManager { public: DataManager(); ~DataManager(); bool Insert(const BackupInfo &info); // 新增 bool Updata(const BackupInfo &info); // 更新 bool GetOneByURL(const std::string &url, BackupInfo* info); // 通过url获取文件信息 bool GetOneByRealpath(const std::string &realpath, BackupInfo* info); // 通过实际路径获取文件信息 bool GetAll(std::vector<BackupInfo>* array); // 获取所有文件信息 bool Storage(); // 每次数据更新或者新增都要持久化存储 bool InitLoad(); // 初始化加载在每次系统启动前都要加载以前的数据 private: std::string _backup_file; // 备份信息持久化存储 pthread_rwlock_t _rwlock; // 读写锁 std::unordered_map<std::string, BackupInfo> _table // 数据信息组织; };
5.数据管理类实现 class DataManager{public: DataManager() { _backup_file Config::GetInstance()->GetBackupFile(); // 获取备份信息持久化存储的文件 pthread_rwlock_init(&_rwlock, NULL); // 初始化读写锁 InitLoad(); // 初始化加载 } ~DataManager() { pthread_rwlock_destroy(&_rwlock); // 释放读写锁 } bool Insert(const BackupInfo &info) { pthread_rwlock_wrlock(&_rwlock); _table[info.url] info; pthread_rwlock_unlock(&_rwlock); return true; } bool Updata(const BackupInfo &info) { pthread_rwlock_wrlock(&_rwlock); _table[info.url] info; pthread_rwlock_unlock(&_rwlock); return true; } bool GetOneByURL(const std::string &url, BackupInfo* info) { pthread_rwlock_wrlock(&_rwlock); auto it _table.find(url); if(it _table.end()) { pthread_rwlock_unlock(&_rwlock); return false; } *info it->second; pthread_rwlock_unlock(&_rwlock); return true; } bool GetOneByRealpath(const std::string &realpath, BackupInfo* info) { pthread_rwlock_wrlock(&_rwlock); auto it _table.begin(); for(; it ! _table.end(); it) { if(it->second.real_path realpath) { *info it->second; pthread_rwlock_unlock(&_rwlock); return true; } } pthread_rwlock_unlock(&_rwlock); return false; } bool GetAll(std::vector<BackupInfo>* array) { pthread_rwlock_wrlock(&_rwlock); auto it _table.begin(); for(; it ! _table.end(); it) { array->push_back(it->second); } pthread_rwlock_unlock(&_rwlock); return true; } bool Storage() { // 1.获取所有数据 std::vector<BackupInfo> array; GetAll(&array); // 2.添加到Json::Value中 Json::Value root; for(int i 0; i < array.size(); i) { Json::Value item; root[pack_flag] array[i].pack_flag; root[fize] (Json::Int64)array[i].fsize; root[atime] (Json::Int64)array[i].atime; root[mtime] (Json::Int64)array[i].mtime; root[real_path] array[i].real_path; root[pack_path] array[i].pack_path; root[url] array[i].url; root.append(item); // 添加数组元素 } // 3.对Json::Value序列化 std::string body; JsonUtil::Serialize(root, &body); // 4.写文件 FileUtil fu(_backup_file); fu.SetContent(body); return true; } bool InitLoad() { // 1.将数据从文件中读取出来 FileUtil fu(_backup_file); if(fu.Exists() false) { return true; } std::string body; fu.GetContent(&body); // 2.反序列化 Json::Value root; JsonUtil::Unserialize(body, &root); // 3.将反序列化得到的Json::Value中的数据添加到table中 for(int i 0; i < root.size(); i) { BackupInfo info; info.pack_flag root[i][pack_flag].asBool(); info.fsize root[i][fsize].asInt64(); info.atime root[i][atime].asInt64(); info.mtime root[i][mtime].asInt64(); info.pack_path root[i][pack_path].asString(); info.real_path root[i][real_path].asString(); info.url root[i][url].asString(); Insert(info); } return true; }private: std::string _backup_file; // 备份信息持久化存储 pthread_rwlock_t _rwlock; // 读写锁 std::unordered_map<std::string, BackupInfo> _table; // 数据信息组织};
6.数据管理模块整理 我们将BackpInfo
与DataManger
的实现都放到data.hpp
中。
// data.hpp#ifndef __MY_DATA__#define __MY_DATA__#include <unordered_map>#include <pthread.h>#include util.hpp#include config.hppnamespace cloud{ typedef struct BackupInfo { bool pack_flag; // 文件是否被压缩标志 size_t fsize; // 文件大小 time_t mtime; // 文件最后一次修改时间 time_t atime; // 文件最后一次访问时间 std::string real_path; // 文件实际存储路径 std::string pack_path; // 压缩包存储路径 std::string url; // 文件访问URL bool NewBackupInfo(const std::string &realpath) { FileUtil fu(realpath); if(fu.Exists() false) { std::cout << new backupinfo: file not exit << std::endl; return false; } Config* config Config::GetInstance(); std::string packdir config->GetPackDir(); std::string packsuffix config->GetPackFileSuffix(); std::string download_prefix config->GetDownloadPrefix(); pack_flag false; fsize fu.FileSize(); mtime fu.LastMtime(); atime fu.LastATime(); real_path realpath; pack_path packdir fu.FileName() packsuffix; url download_prefix fu.FileName(); return true; } }BackupInfo; class DataManager { public: DataManager() { _backup_file Config::GetInstance()->GetBackupFile(); // 获取备份信息持久化存储的文件 pthread_rwlock_init(&_rwlock, NULL); // 初始化读写锁 InitLoad(); // 初始化加载 } ~DataManager() { pthread_rwlock_destroy(&_rwlock); // 释放读写锁 } bool Insert(const BackupInfo &info) { pthread_rwlock_wrlock(&_rwlock); _table[info.url] info; pthread_rwlock_unlock(&_rwlock); return true; } bool Updata(const BackupInfo &info) { pthread_rwlock_wrlock(&_rwlock); _table[info.url] info; pthread_rwlock_unlock(&_rwlock); return true; } bool GetOneByURL(const std::string &url, BackupInfo* info) { pthread_rwlock_wrlock(&_rwlock); auto it _table.find(url); if(it _table.end()) { pthread_rwlock_unlock(&_rwlock); return false; } *info it->second; pthread_rwlock_unlock(&_rwlock); return true; } bool GetOneByRealpath(const std::string &realpath, BackupInfo* info) { pthread_rwlock_wrlock(&_rwlock); auto it _table.begin(); for(; it ! _table.end(); it) { if(it->second.real_path realpath) { *info it->second; pthread_rwlock_unlock(&_rwlock); return true; } } pthread_rwlock_unlock(&_rwlock); return false; } bool GetAll(std::vector<BackupInfo>* array) { pthread_rwlock_wrlock(&_rwlock); auto it _table.begin(); for(; it ! _table.end(); it) { array->push_back(it->second); } pthread_rwlock_unlock(&_rwlock); return true; } bool Storage() { // 1.获取所有数据 std::vector<BackupInfo> array; GetAll(&array); // 2.添加到Json::Value中 Json::Value root; for(int i 0; i < array.size(); i) { Json::Value item; root[pack_flag] array[i].pack_flag; root[fize] (Json::Int64)array[i].fsize; root[atime] (Json::Int64)array[i].atime; root[mtime] (Json::Int64)array[i].mtime; root[real_path] array[i].real_path; root[pack_path] array[i].pack_path; root[url] array[i].url; root.append(item); // 添加数组元素 } // 3.对Json::Value序列化 std::string body; JsonUtil::Serialize(root, &body); // 4.写文件 FileUtil fu(_backup_file); fu.SetContent(body); return true; } bool InitLoad() { // 1.将数据从文件中读取出来 FileUtil fu(_backup_file); if(fu.Exists() false) { return true; } std::string body; fu.GetContent(&body); // 2.反序列化 Json::Value root; JsonUtil::Unserialize(body, &root); // 3.将反序列化得到的Json::Value中的数据添加到table中 for(int i 0; i < root.size(); i) { BackupInfo info; info.pack_flag root[i][pack_flag].asBool(); info.fsize root[i][fsize].asInt64(); info.atime root[i][atime].asInt64(); info.mtime root[i][mtime].asInt64(); info.pack_path root[i][pack_path].asString(); info.real_path root[i][real_path].asString(); info.url root[i][url].asString(); Insert(info); } return true; } private: std::string _backup_file; // 备份信息持久化存储 pthread_rwlock_t _rwlock; // 读写锁 std::unordered_map<std::string, BackupInfo> _table; // 数据信息组织 };}#endif
标签: