⚡文件信息管理模块⚡
Posted 努力学习的少年
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了⚡文件信息管理模块⚡相关的知识,希望对你有一定的参考价值。
目录
🌳. FileInfoManger类的设计(文件信息管理类)
🌳.文件信息管理模块介绍
- 在云备份服务器上,每一个文件都有一个FileInfo的类对象管理该文件的信息,包括文件压缩标志,文件大小,最近访问时间,修改时间,压缩路径,备份路径。
- 备份在云服务器的所有文件信息用json字符串的形式备份在一个backfileinfo文件持久化存储。
- 当服务器在启动的时候,文件信息管理模块会将backfileinfo文件中的所有的文件信息读取上来,将
- 所有的文件信息以备份路径-FileInfo的形式进行映射在哈希表中,方便服务器查询文件信息。
🌳.FileInfo类的设计
FileInfo类的变量:
- 压缩标志:用来判断文件是否被压缩
- 备份路径:文件存储在热点的目录的路径,一般为/packdir/test.txt
- 压缩路径:文件存储在非热点目录的路径,一般为/backdir/test.txt
- url:文件下载请求的路径,一般为/download/test.txt
- 文件大小
- 最后一次访问的时间
- 最后一次修改的时间
FileInfo类的构造函数,使用配置模块和文件工具类初始化FileInfo中的成员变量
#include"Config.hpp"
class FileInfo
public:
bool pack_sign;
size_t file_size;
time_t access_time;
time_t modify_time;
std::string back_path;
std::string pack_path;
std::string url;
public:
FileInfo(const std::string& backpath)
AddFileInfo(backpath);
FileInfo()
bool AddFileInfo(const std::string& backpath)
sjp::FileUtil fu(backpath.c_str());
file_size=fu.GetFileSize();
pack_sign=false;
access_time=fu.GetFileAccessTime();
modify_time=fu.GetFileModfityTime();
back_path=sjp::Config::GetInstant()->GetBackDir();
back_path+=fu.GetFilename();
pack_path=sjp::Config::GetInstant()->GetPackDir();
pack_path+=fu.GetFilename();
pack_path+=sjp::Config::GetInstant()->GetPackFileSuffix();
url="/download/";
url+=fu.GetFilename();
return true;
;
🌳. FileInfoManger类的设计(文件信息管理类)
🍎.FileInfoManger类的成员变量
- file_info_path:backfileinfo文件路径,方便加载文件信息。
- _table:哈希表,将文件的备份路径与文件信息映射起来,方便服务器能够查找文件信息。
- _rwlock:读写锁,保证信息管理模块在访问和修改哈希表的过程中线程安全的。
🍎.成员函数
InitLoad函数
InitLoad函数的功能加载backfileinfo文件中的所有的文件信息加载到FileInfoManger对象里面。
//将文件上的信息加载到内存中
bool InitLoad()
/*
* 1.打开备份文件的存储信息
2.将存储信息读取到body中
3.将body进行反序列化为root;
4.将各个文件信息加载到table中
*/
sjp::FileUtil fu(file_info_path.c_str());
std::string body;
fu.GetContent(body);
Json::Value root;
sjp::JsonUtil::UnSerialize(root,body);
W> for(int i=0;i<root.size();i++)
FileInfo fileinfo;
fileinfo.access_time=root[i]["AccessTime"].asInt();
fileinfo.modify_time=root[i]["ModifyTime"].asInt();
fileinfo.back_path=root[i]["BackPath"].asString();
fileinfo.pack_path=root[i]["PackPath"].asString();
fileinfo.file_size=root[i]["FileSize"].asInt();
fileinfo.pack_sign=root[i]["PackSign"].asBool();
fileinfo.url=root[i]["Url"].asString();
Insert(fileinfo);
return true;
UpdateFileInfo函数
UpdateFileInfo的功能是查看backdir下的文件信息是否全都存储在backfileinfo,如果某些文件没有存储,则将该文件的信息存储进backfileinfo里面。
实现思路:
- 获取backdir下的所有文件,将所有的文件与_table进行比对。
- 如果某个文件在_table中没有找到,说明该文件信息没有持久化进backfileinfo文件里,创建该文件信息,将该文件的信息插入到_table,最后在将更新backfileinfo中的数据。
bool UpdateFileInfo()
std::string path=sjp::Config::GetInstant()->GetBackDir();
sjp::FileUtil fu(path);
std::vector<std::string> arry;
fu.GetPathInDir(arry);
W> for(int i=0;i<arry.size();i++)
auto it=_table.find(arry[i]);
if(it==_table.end())
//>
//没有将该文件信息存储到信息系统中
sjp::FileInfo fileinfo(arry[i]);
Insert(fileinfo);
Storage();
W>
Storage函数
Storage函数的功能将_table中的所有信息持久化存储到backfileinfo文件里面。
实现思路:
- 将_table上的所有的文件信息都存储在Json::Value root中,在将root序列化为Json字符串,最后再通过文件工具类打开backfileinfo文件,将Json字符串写入到backfile文件中。
//将table上的所有信息存储持久化到文件上
bool Storage()
//将文件的备份信息反序列化字符并组织到body上
std::string filebody;
Json::Value root;
std::string body;
auto it=_table.begin();
int i=0;
while(it!=_table.end())
root[i]["AccessTime"]=(Json::Int)it->second.access_time;
root[i]["ModifyTime"]=(Json::Int)it->second.modify_time;
root[i]["FileSize"]=(Json::Int)it->second.file_size;
root[i]["Url"]=it->second.url;
root[i]["PackSign"]=it->second.pack_sign;
root[i]["BackPath"]=it->second.back_path;
root[i]["PackPath"]=it->second.pack_path;
i++;
it++;
sjp::JsonUtil::Serialize(root,body);
sjp::FileUtil fu(file_info_path.c_str());
if(!fu.SetContent(body))
return false;
return true;
UpdatePackSign函数
UpdatePackSign函数的功能是将packdir中的下文件信息中的压缩标志为false,则更改为true,表示该文件已经被压缩。
bool UpdatePackSign()
cout<<"Updatepacksign"<<endl;
auto it=_table.begin();
while(it!=_table.end())
sjp::FileUtil fu(it->second.pack_path);
if(fu.Exist())
it->second.pack_sign=true;
Insert(it->second);
it++;
Storage();
W>
构造函数
- 云备份服务器启动时,需要先使用InitLoad函数将backfileinfo中的文件加载到_table中。
- 利用UpdateFileInfo函数更新backdir目录下的文件没有存放进backfileinfo文件信息。
- 利用 UpdatePackSign函数将packdir目录下文件的文件信息的压缩标志是false修改为true;
FileInfoManger()
file_info_path=Config::GetInstant()->GetBackFileInfo();
pthread_rwlock_init(&_rwlock,NULL);
InitLoad();
UpdateFileInfo();
UpdatePackSign();
其它函数
#pragma once
#include"Config.hpp"
#include<unordered_map>
#include<pthread.h>
namespace sjp
class FileInfoManger
private:
std::string file_info_path;//存储文件信息的持久化文件
std::unordered_map<std::string,FileInfo> _table; //backpath-info
pthread_rwlock_t _rwlock;//读写锁
private:
static FileInfoManger* instant;
static std::mutex lock;
private:
FileInfoManger(FileInfoManger&)=delete;
public:
static FileInfoManger* GetInstant()
if(instant==nullptr)
lock.lock();
if(instant==nullptr)
instant=new FileInfoManger();
lock.unlock();
return instant;
//插入信息
bool Insert(const FileInfo& info)
pthread_rwlock_wrlock(&_rwlock);
_table[info.back_path]=info;
pthread_rwlock_unlock(&_rwlock);
return true;
//更新信息
bool update(const FileInfo& info)
pthread_rwlock_wrlock(&_rwlock);
_table[info.back_path]=info;
pthread_rwlock_unlock(&_rwlock);
return true;
//通过backpath判断该文件是否存在
bool Exist(const std::string& backpath)
auto it=_table.find(backpath);
if(it!=_table.end())
return true;
return false;
//通过url获取文件信息
bool GetoneByURL(const std::string& url,FileInfo& info)
sjp::FileUtil fu(url);
std::string backpath=sjp::Config::GetInstant()->GetBackDir();
backpath+=fu.GetFilename();
return GetOneByRealPath(backpath,info);
//通过相对路径获取文件信息
bool GetOneByRealPath(const std::string& backpath,FileInfo& info)
auto it=_table.find(backpath);
if(it!=_table.end())
info=it->second;
return true;
return false;
//获取所有备份文件的文件信息
bool GetAllInfo( std::vector<FileInfo>& arry)
pthread_rwlock_wrlock(&_rwlock);
auto it=_table.begin();
while(it!=_table.end())
arry.push_back(it->second);
it++;
pthread_rwlock_unlock(&_rwlock);
return true;
~FileInfoManger()
Storage();
;
FileInfoManger* FileInfoManger::instant=nullptr;
std::mutex FileInfoManger::lock;
以上是关于⚡文件信息管理模块⚡的主要内容,如果未能解决你的问题,请参考以下文章