【云备份|| 日志 day4】文件信息管理模块

已经写到后边去了,但是这几天改bug改的很恼火,就没有写项目日志

在这里插入图片描述

数据管理模块 ------DataManager

我们要对服务器上存在的文件进行数据管理,就要遵循

先描述,后组织的 的原则,我们需要知道文件的状态和信息,将其描述成为一个结构体,然后在对其进行管理。

服务端模块实现-管理的数据信息

文件实际存储路径
文件是否压缩标志
压缩包存储路径
文件访问URL
文件最后一次修改时间
文件最后一次访问时间
文件大小

服务端数据管理模块实现-如何管理数据
内存中以文件访问URL为key,数据信息结构为val,使用哈希表进行管理,查询速度快。使用url作为key是因为往后客户端浏览器下载文件的时候总是以 url 作为请求。
采用文件形式对数据进行持久化存储(序列化方式采用 json 格式或者自定义方式)

文件信息:

typedef struct BackupInfo{
	int pack_flag;
	time_t mtime;
	time_t atime;
	size_t fsize;
	std::string realpath;
	std::string url;
	std::string packpath;
	bool NewBackupInfo(const std::string &realpath);
}BackupInfo;

管理模块:
无非就是对数据的增删查改

class DataManager{
private:
	FileUtil _backup_file;
	pthread_rwlock_t _rwlock;
	std::unordered_map<std::string, BackupInfo> _table;
public:
	DataManager();
	bool InitLoad();//初始化程序运行时从文件读取数据
	bool Storage(); //每次有信息改变则需要持久化存储一次
	bool Insert(const std::string &key, const BackupInfo &val);
	bool Update(const std::string &key, const BackupInfo &val);
	bool GetOneByURL(const std::string &key, BackupInfo *info);
	bool GetOneByRealPath(const std::string &key, BackupInfo *info);
	bool GetAll(std::vector<BackupInfo> *arry);
};

代码:

	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;
		bool NewBackupInfo(const std::string &realpath){
			FileUtil fu(realpath);
			if (fu.Exists() == false) {
				std::cout << "new backupinfo: file not exists!\n";
				return false;
			}
			Config *config = Config::GetInstance();
			std::string packdir = config->GetPackDir();
			std::string packsuffix = config->GetPackFileSuffix();
			std::string download_prefix = config->GetDownloadPrefix();
			this->pack_flag = false;
			this->fsize = fu.FileSize();
			this->mtime = fu.LastMTime();
			this->atime = fu.LastATime();
			this->real_path = realpath;
			// ./backdir/a.txt   ->   ./packdir/a.txt.lz
			this->pack_path = packdir + fu.FileName() + packsuffix;
			// ./backdir/a.txt   ->	  /download/a.txt
			this->url = download_prefix + fu.FileName();
			return true;
		}
	}BackupInfo;

	class DataManager{
		private:
			std::string _backup_file;
			pthread_rwlock_t _rwlock;
			std::unordered_map<std::string, BackupInfo> _table;
		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);
				Storage();
				return true;
			}
			bool Update(const BackupInfo &info) {
				pthread_rwlock_wrlock(&_rwlock);
				_table[info.url] = info;
				pthread_rwlock_unlock(&_rwlock);
				Storage();
				return true;
			}
			bool GetOneByURL(const std::string &url, BackupInfo *info) {
				pthread_rwlock_wrlock(&_rwlock);
				//因为url是key值,所以直接通过find进行查找
				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> *arry) {
				pthread_rwlock_wrlock(&_rwlock);
				auto it = _table.begin();
				for (; it != _table.end(); ++it){
					arry->push_back(it->second);
				}
				pthread_rwlock_unlock(&_rwlock);
				return true;
			}

			bool Storage(){
				//1. 获取所有数据
				std::vector<BackupInfo> arry;
				this->GetAll(&arry);
				//2. 添加到Json::Value
				Json::Value root;
				for (int i = 0; i < arry.size(); i++){
					Json::Value item;
					item["pack_flag"] = arry[i].pack_flag;
					item["fsize"] = (Json::Int64)arry[i].fsize;
					item["atime"] = (Json::Int64)arry[i].atime;
					item["mtime"] = (Json::Int64)arry[i].mtime;
					item["real_path"] = arry[i].real_path;
					item["pack_path"] = arry[i].pack_path;
					item["url"] = arry[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;
			}
	};
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值