Linux(CentOS)/Windows-C++ 云备份项目(服务器数据管理模块设计)

数据管理模块功能:
后续项目需要使用的数据如下

  1. 文件实际存储路径:当客户端需要下载文件时,从这个文件中进行读取响应
  2. 文件压缩包存放路径名:如果文件是非热点文件会被压缩
    如果客户端需要下载这些文件,需要先进行解压缩,然后返回
  3. 文件是否被压缩的标记位:判断文件是否被压缩了
  4. 文件大小,文件最后一次修改时间,文件最后一次访问时间
  5. 文件访问url中的资源路径path

数据管理模块管理数据方式:

  1. 用于数据信息访问:使用哈希表,在内存中管理数据,url的path作为key值
  2. 持久化存储管理:使用json序列化,将所有数据信息保存在文件中(不使用数据库)

数据管理模块被多个线程共享,使用读写锁更好(读共享,写互斥)。每次数据更新都要重新持久化存储,避免数据丢失。每次服务器重启都要加载以前的数据

文件数据结构体设计如下:

#pragma once
#include "./util/fileutil.hpp"
#include <unordered_map>
#include <pthread.h>
#include "./config/config.hpp"
namespace CloudBackups
{struct BackupInfo{bool packflag;         // 压缩标记size_t size;           // 文件大小time_t mtime;          // 最后一次修改时间time_t atime;          // 最后一次访问时间std::string real_path; // 实际文件存储位置std::string pack_path; // 文件压缩存储位置std::string url;// 打开文件初始化BackInfoBackupInfo(const std::string &real_path){this->packflag = false;FileUtil file(real_path);if (file.isExit()) // 文件存在时才可以获取下面的信息{this->size = file.filesize();this->mtime = file.last_modify_time();this->atime = file.last_visit_time();this->real_path = real_path;// 获取配置文件的压缩文件路径Config *config = Config::GetInstance();std::string packdir = config->GetPackfileDir();   // 压缩文件根目录std::string suffix = config->GetPackfileSuffix(); // 压缩文件后缀std::string zipname = file.filename() + suffix;this->pack_path = packdir + "/" + zipname; // 压缩文件路径std::string download = config->GetDownloadPrefix();this->url = download + "/" + file.filename(); // 下载请求路径}else{LOG(FATAL, "file not found");}}};
}

数据管理模块设计如下:

#pragma once
#include "./util/fileutil.hpp"
#include <unordered_map>
#include <pthread.h>
#include "./config/config.hpp"
#include "./util/json.hpp"
namespace CloudBackups
{class DataMange{private:pthread_rwlock_t rwlock;                               // 读写锁,读共享,写互斥std::unordered_map<std::string, BackupInfo> backupMap; // 文件请求路径和对应信息的哈希表std::string backupFile;                                // 数据持久化信息文件,文件格式为jsonpublic:// 将backupMap持久化存储bool Storage(){// 获取所有数据std::vector<BackupInfo> backups;this->GetAll(backups);// 添加到Json::Value中Json::Value root;for (size_t i = 0; i < backups.size(); i++){Json::Value backup;backup["packflag"] = backups[i].packflag;backup["size"] = Json::Int64(backups[i].size);backup["mtime"] = Json::Int64(backups[i].mtime);backup["atime"] = Json::Int64(backups[i].atime);backup["real_path"] = backups[i].real_path;backup["pack_path"] = backups[i].pack_path;backup["url"] = backups[i].url;root.append(backup);}// 持久化 序列化+保存//  序列化std::string body;JsonUtil::serialize(root, body);// 保存文件FileUtil file(backupFile);file.setContent(body);return true;}// 加载配置信息,初始化backupMapbool InitLoad(){// 读取Json文件FileUtil file(backupFile);if (file.isExit() == false){// 服务器文件信息不存在,无需初始化return true;}std::string body;file.getContent(body);// 反序列化Json::Value root;if (JsonUtil::unserialize(body, root) == true){// 将反序列化的数据写到map上for (int i = 0; i < root.size(); i++){BackupInfo backupInfo;backupInfo.packflag = root[i]["packflag"].asBool();backupInfo.size = root[i]["size"].asInt64();backupInfo.mtime = root[i]["mtime"].asInt64();backupInfo.atime = root[i]["atime"].asInt64();backupInfo.real_path = root[i]["real_path"].asString();backupInfo.pack_path = root[i]["pack_path"].asString();backupInfo.url = root[i]["url"].asString();Insert(backupInfo);}return true;}return false;}DataMange(){backupFile = Config::GetInstance()->GetBackupFile();pthread_rwlock_init(&rwlock, nullptr);InitLoad();}~DataMange(){pthread_rwlock_destroy(&rwlock);}// 数据管理模块插入信息bool Insert(const BackupInfo &backupInfo){pthread_rwlock_wrlock(&rwlock);backupMap[backupInfo.url] = backupInfo;pthread_rwlock_unlock(&rwlock);Storage();return true;}// 更新数据管理模块bool UpDate(const BackupInfo &backupInfo){pthread_rwlock_wrlock(&rwlock);backupMap[backupInfo.url] = backupInfo;pthread_rwlock_unlock(&rwlock);Storage();return true;}// 通过url获取这个文件bool GetByUrl(const std::string &url, BackupInfo &backupInfo){pthread_rwlock_wrlock(&rwlock);auto pos = backupMap.find(url);if (pos == backupMap.end()){LOG(WARNING, "url map not found you url is: " + url);pthread_rwlock_unlock(&rwlock);return false;}backupInfo = pos->second;pthread_rwlock_unlock(&rwlock);return true;}// 通过http uri 获取文件信息bool GetByRealPath(const std::string &real_url, BackupInfo &backupInfo){pthread_rwlock_wrlock(&rwlock);auto pos = backupMap.begin();while (pos != backupMap.end()){if (pos->second.real_path == real_url){backupInfo = pos->second;pthread_rwlock_unlock(&rwlock);return true;}pos++;}LOG(WARNING, "http uti not found you uri is: " + real_url);pthread_rwlock_unlock(&rwlock);return false;}// 获取请求映射下所有文件信息bool GetAll(std::vector<BackupInfo> &backups){pthread_rwlock_wrlock(&rwlock);backups.clear();for (auto &backup : backupMap){backups.push_back(backup.second);}pthread_rwlock_unlock(&rwlock);return true;}};
}

Gitee位置
Github位置

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/772792.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用Flask实现:基于midjourney-proxy的MJ绘画实现(开源)

文章目录 实现效果实现步骤完整源码 实现效果 运行mj.py&#xff0c;如下所示。输入中文&#xff0c;自动生成提示词&#xff0c;自动开始下载。用户选择是否需要变换图片&#xff0c;选择需要对哪个图片变换&#xff0c;自动保存。 之前想做一个网页版&#xff0c;只实现了…

一些常见的ClickHouse问题和答案

什么是ClickHouse&#xff1f;它与其他数据库系统有什么区别&#xff1f; ClickHouse是一个开源的列式数据库管理系统&#xff08;DBMS&#xff09;&#xff0c;专门用于高性能、大规模数据分析。与传统的行式数据库相比&#xff0c;ClickHouse具有更高的查询性能、更高的数据…

新书速览|Django 5企业级Web应用开发实战:视频教学版

掌握Django框架开发技能&#xff0c;实战投票应用系统和内容管理系统 本书内容 《Django 5企业级Web应用开发实战&#xff1a;视频教学版》精选当前简单、实用和流行的Django实例代码&#xff0c;帮助读者学习和掌握Django 5框架及其相关技术栈的开发知识。本书系统全面、内容…

【STM32学习计划】

项目名称&#xff1a;STM32学习计划 项目目标&#xff1a; 熟悉STM32单片机的基本概念和应用掌握STM32的软硬件开发流程完成一个基于STM32的简单项目 项目任务和交付物&#xff1a; 任务 1&#xff1a;熟悉STM32单片机基本概念 学习STM32单片机的基本架构和功能特性交付物…

mysql如何存Emoji表情

如何存Emoji表情 背景解决方案一&#xff1a; 如果是自己搭建的数据库&#xff0c;参考如下。 1&#xff1a;先创建数据库&#xff0c;utf8编码2&#xff1a; 修改mysql 的配置文件 /etc/my.cnf 文件3&#xff1a;然后把你的表和字段也要支持utf8md4编码4&#xff1a;修改你连…

javaWeb教务查询系统

一、简介 在教育管理领域&#xff0c;教务管理系统是一个至关重要的工具&#xff0c;它能够有效地协调学校、教师和学生之间的各种活动。我设计了一个基于JavaWeb的教务管理系统&#xff0c;该系统包括三个角色&#xff1a;管理员、教师和学生。管理员拥有课程管理、学生管理、…

Spark重温笔记(五):SparkSQL进阶操作——迭代计算,开窗函数,结合多种数据源,UDF自定义函数

Spark学习笔记 前言&#xff1a;今天是温习 Spark 的第 5 天啦&#xff01;主要梳理了 SparkSQL 的进阶操作&#xff0c;包括spark结合hive做离线数仓&#xff0c;以及结合mysql&#xff0c;dataframe&#xff0c;以及最为核心的迭代计算逻辑-udf函数等&#xff0c;以及演示了几…

JWT(JSON Web Token)

JSON Web Token 是一种开放标准&#xff0c;用于在网络上安全传输信息的简洁、自包含的方式。它通常被用于身份验证和授权机制。 JWT 由三部分组成&#xff1a;头部&#xff08;Header&#xff09;、载荷&#xff08;Payload&#xff09;和签名&#xff08;Signature&#xff…

微软开源项目Garnet:Redis的竞争者还是替代者?

对于开源社区&#xff0c;最近的一大新闻就是Redis宣布从7.4版本开始&#xff0c;将采用Redis源代码可用许可证&#xff08;RSALv2&#xff09;和服务器端公共许可证&#xff08;SSPLv1&#xff09;的双重许可证&#xff0c;取代原有的BSD三条款许可证。这一变化引发了开发者社…

阿里云子域名配置,且不带端口访问

进入阿里云控制台&#xff0c;创建一个SSL证书 # 域名名称child.domain.com创建完成后&#xff0c;将返回主机记录以及记录值&#xff0c;保存好&#xff0c;用于下一步使用 创建DNS解析 创建DNS的TXT类型解析 选择记录类型&#xff1a;TXT 填写主机记录&#xff1a;_dnsa…

一些常见的与 Vim 相关的文件类型及其描述

配置文件&#xff1a; .vimrc (Unix/Linux) 或 _vimrc (Windows)&#xff1a;这是 Vim 的主要配置文件&#xff0c;用户可以在其中设置各种选项、快捷键映射、插件加载等。Vim 在启动时会自动读取这个文件&#xff0c;并根据其中的设置来配置编辑器。init.vim&#xff1a;对于 …

【CSP试题回顾】202104-2-邻域均值(优化)

CSP-202104-2-邻域均值 关键点&#xff1a;二维前缀和数组 详见&#xff1a; 【CSP考题扩展】前缀和/差分练习【CSP考点回顾】二维前缀和数组&#xff08;代码实现&#xff09; 解题思路 1.输入和初始化 首先&#xff0c;程序从输入中获取四个整数n&#xff08;矩阵的大小…

排序(冒泡/快速/归并)

冒泡排序 时间复杂度为 O(n^2) 原理 比较相邻的元素. 如果第一个比第二个大,就交换他们两个.依次比较每一对相邻的元素—>结果 : 最后的元素是这组数中最大的重复上述步骤 , 除了最后一个[]因为最后一个已经是排好序的了(这组数中最大的那个)]持续对越来越少的元素进行如上…

系列学习前端之第 7 章:一文掌握 AJAX

1、AJAX 简介 AJAX 全称为 Asynchronous JavaScript And XML&#xff08;中文名&#xff1a;阿贾克斯&#xff09;&#xff0c;就是异步的 JS 和 XML。AJAX 不是新的编程语言&#xff0c;而是一种将现有的标准组合在一起使用的新方式。AJAX 可以在浏览器中向服务器发送异步请求…

docker拉取镜像

docker 拉取镜像 命令格式 docker pull 仓库名称[:标签] 从下载过程可以看出&#xff1a; &#xff08;1&#xff09;镜像文件是由若干层组成&#xff0c;即&#xff1a;AUFS联合文件系统。这是实现增量保存与更新的基础 &#xff08;2&#xff09;下载过程会输出各层镜像的信…

面试题-Elasticsearch集群架构和调优手段(超全面)

对于Elasticsearch&#xff08;ES&#xff09;&#xff0c;我了解并有经验。在我之前的公司&#xff0c;我们有一个相对大型的ES集群&#xff0c;以下是该集群的架构和一些调优手段的概述&#xff1a; 1. 集群架构 集群规模&#xff1a;我们的ES集群由15个节点组成&#xff0c…

水果店如何开发自己的微信小程序_新鲜生活,触手可及

水果店微信小程序&#xff1a;新鲜生活&#xff0c;触手可及 在这个快节奏的时代&#xff0c;我们都在追求更高效、更便捷的生活方式。而微信小程序&#xff0c;正是这样一个让生活变得更加轻松便捷的神奇工具。今天&#xff0c;我要向大家介绍的&#xff0c;就是一家独具匠心…

独享IP可以避免被封禁或限制访问的风险

在一些网站或服务中&#xff0c;存在对共享IP的封禁或限制访问的情况&#xff0c;这给用户带来了不便。而使用独享IP可以有效规避这一问题&#xff0c;保障用户正常访问需求。例如&#xff0c;在进行搜索引擎优化、社交媒体营销或广告投放时&#xff0c;独享IP可以确保用户的网…

window下迁移SVN仓库到新的windows服务器

一、背景 一个基于 Windows 的 SVN 服务器&#xff0c;用于管理团队的代码库。该 SVN 仓库托管着公司的软件项目&#xff0c;包括多个分支和版本的代码。我们的团队规模约为 50 人&#xff0c;分布在不同的地理位置&#xff0c;他们都依赖 SVN 仓库来进行代码版本控制和协作开…

LeetCode146:LRU缓存

leetCode&#xff1a;146. LRU 缓存 题目描述 请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。 实现 LRUCache 类&#xff1a; LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存 int get(int key) 如果关键字 key 存在于缓存中&#x…