文章目录
要管理的数据信息
文件实际存储路径
文件是否压缩标志
压缩包存储路径
文件访问URL
文件最后一次修改时间
文件最后一次访问时间
文件大小
管理数据的方式
内存中以文件访问URL为key,数据信息结构为val,使用哈希表进行管理,查询速度快。使用url作为key是因为往后客户端浏览器下载文件的时候总是以 url 作为请求。
采用文件形式对数据进行持久化存储(序列化方式采用 json 格式或者自定义方式)
数据管理类的实现
数据信息设计成结构体
struct BackupInfo
{
bool pack_flag;//文件压缩标志位
size_t file_size;//文件大小
time_t modify_time;//最后一次修改时间
time_t access_time;//最后一次访问时间
std::string real_path;//文件真实路径
std::string pack_path;//文件压缩路径
std::string url;//文件的url
bool NewBackupInfo(const std::string& filepath)
{
//std::cout << filepath << std::endl;
//1.获取文件内容
fileUtil fu(filepath);
if(fu.exists() == false)
{
std::cout << "NewBackupInfo fail" << std::endl;
return false;
}
//2.设置文件内容信息到类中
pack_flag = false;
//std::cout << fu.fileSize() << std::endl;
file_size = fu.fileSize();
modify_time = fu.lastModifyTime();
access_time = fu.lastAccessTime();
real_path = filepath;
Config* f = Config::getIstance();
std::string packdir = f->getPackDir();
std::string packfile_suffix = f->getPackfileSuffix();
pack_path = packdir + fu.fileName() + packfile_suffix;
std::string download_prefix = f->getDownloadPrefix();
url = download_prefix + fu.fileName();
return true;
}
};
数据管理类
成员变量
private:
std::string _backup_file;//备份文件信息的文件名
pthread_rwlock_t _rwlock;//读写锁
std::unordered_map<std::string, BackupInfo> _table;//保存文件信息的哈希表
成员函数
dataManager()
{
_backup_file = Config::getIstance()->getBackupFile();//获取备份信息文件
pthread_rwlock_init(&_rwlock, nullptr);//初始化读写锁
initLoad();//初始化程序运行时从文件读取数据
}
bool initLoad()//初始化程序运行时从文件读取数据
{}
bool storage() //每次有信息改变则需要持久化存储到文件中
{}
bool insert(const BackupInfo& Info)//插入数据
{}
bool update(const BackupInfo& Info)//更新数据
{}
bool getBifoByUrl(const std::string& url, BackupInfo* Info)//根据Url获取数据
{}
bool getBifoByRealPath(const std::string& realPath, BackupInfo* Info)//根据RealPath获取数据
{}
bool getAll(std::vector<BackupInfo> *arry)//获取所有备份信息
{}
~dataManager()
{
pthread_rwlock_destroy(&_rwlock);//销毁读写锁
}
增查改+获取
insert
bool insert(const BackupInfo& Info)
{
//存在多执行流同时访问的可能,所以需要加锁
pthread_rwlock_wrlock(&_rwlock);
_table[Info.url] = Info;
pthread_rwlock_unlock(&_rwlock);
storage();//持久化存储
return true;
}
update
bool update(const BackupInfo& Info)
{
//存在多执行流同时访问的可能,所以需要加锁
pthread_rwlock_wrlock(&_rwlock);
_table[Info.url] = Info;
pthread_rwlock_unlock(&_rwlock);
storage();//持久化存储
return true;
}
getBifoByUrl
bool getBifoByUrl(const std::string& url, BackupInfo* Info)
{
//存在多执行流同时访问的可能,所以需要加锁
pthread_rwlock_wrlock(&_rwlock);
auto ret = _table.find(url);
if(ret == _table.end())
{
pthread_rwlock_unlock(&_rwlock);
return false;
}
*Info = ret->second;
pthread_rwlock_unlock(&_rwlock);
return true;
}
getBifoByRealPath
bool getBifoByRealPath(const std::string& realPath, BackupInfo* Info)
{
//存在多执行流同时访问的可能,所以需要加锁
pthread_rwlock_wrlock(&_rwlock);
for(auto& e : _table)
{
if(e.second.real_path == realPath)
{
*Info = e.second;
pthread_rwlock_unlock(&_rwlock);
return true;
}
}
pthread_rwlock_unlock(&_rwlock);
return false;
}
getAll
bool getAll(std::vector<BackupInfo> *arry)
{
//存在多执行流同时访问的可能,所以需要加锁
pthread_rwlock_wrlock(&_rwlock);
for(auto& e : _table)
{
arry->push_back(e.second);
}
pthread_rwlock_unlock(&_rwlock);
return true;
}
持久化存储和加载信息
initLoad
bool initLoad()//初始化程序运行时从文件读取数据
{
//1.读取文件内容
fileUtil fu(_backup_file);
if(fu.exists() == false)
{
return true;
}
std::string body;
bool ret = fu.getContent(&body);
if(ret == false)
{
std::cout << "InitLoad getContent failed" << std::endl;
return false;
}
//2.对文件内容进行反序列化
Json::Value root;
ret = JsonUtil::UnSerialize(body, &root);
if(ret == false)
{
std::cout << "InitLoad getContent failed" << std::endl;
return false;
}
//3.增加所有文件信息到哈希表中
for(int i = 0; i < root.size(); i++)
{
BackupInfo info;
info.pack_flag = root[i]["pack_flag"].asBool();
info.file_size = root[i]["file_size"].asInt64();
info.modify_time = root[i]["modify_time"].asInt64();
info.access_time = root[i]["access_time"].asInt64();
info.real_path = root[i]["real_path"].asString();
info.pack_path = root[i]["pack_path"].asString();
info.url = root[i]["url"].asString();
//_table[info.url] = info;
insert(info);
}
return true;
}
storage
bool storage() //每次有信息改变则需要持久化存储一次
{
//1.获取所有文件信息进行序列化
Json::Value root;
for(auto& e : _table)
{
Json::Value tmp;
tmp["pack_flag"] = e.second.pack_flag;
tmp["file_size"] = (Json::Int64)e.second.file_size;
tmp["modify_time"] = (Json::Int64)e.second.modify_time;
tmp["access_time"] = (Json::Int64)e.second.access_time;
tmp["real_path"] = e.second.real_path;
tmp["pack_path"] = e.second.pack_path;
tmp["url"] = e.second.url;
root.append(tmp);
}
//2.对所有信息数据进行序列化
std::string body;
bool ret = JsonUtil::Serialize(root, &body);
if(ret == false)
{
std::cout << "Storage Serialize faile" << std::endl;
return false;
}
//3.信息数据写入到文件中
fileUtil fu(_backup_file);
ret = fu.setContent(body);
if(ret == false)
{
std::cout << "Storage setContent faile" << std::endl;
return false;
}
return true;
}