【lesson8】云备份服务端完整版代码
文章目录
- util.hpp
- config.hpp
- hot.hpp
- data.hpp
- server.hpp
- server.cc
- Makefile
- cloud.conf
util.hpp
#pragma once #include #include #include #include #include #include #include #include #include #include #include #include "bundle.h" namespace cloud { namespace fs = std::experimental::filesystem; class fileUtil { public: fileUtil(std::string filename) :_filename(filename) {} bool Remove() { if(exists() == false) { return true; } remove(_filename.c_str()); return true; } size_t fileSize() { struct stat st; int ret = stat(_filename.c_str(), &st); if(ret == -1) { std::cout struct stat st; int ret = stat(_filename.c_str(), &st); if(ret == -1) { std::cout struct stat st; int ret = stat(_filename.c_str(), &st); if(ret == -1) { std::cout size_t pos = _filename.find_last_of("/"); if(pos == std::string::npos) { return _filename; } return _filename.substr(pos + 1); } bool setContent(const std::string &body) { std::ofstream ofs; ofs.open(_filename, std::ios::binary); if(ofs.is_open() == false) { std::cout std::cout std::ifstream ifs; if(pos + len fileSize()) { std::cout std::cout std::cout size_t n = fileSize(); return getPosLen(body, 0, n); } bool exists() { return fs::exists(_filename); } bool createDirectory() { if(exists()) return true; return fs::create_directories(_filename); } bool getDirectory(std::vector for(const fs::directory_entry& entry : fs::directory_iterator{_filename}) { if(fs::is_directory(entry)) continue; arry-push_back(fs::path(entry).relative_path().string()); } return true; } bool compress(const std::string &packname) { std::string body; getContent(&body); std::string buffer = bundle::pack(bundle::LZIP, body); std::ofstream ofs; ofs.open(packname, std::ios::binary); if(ofs.is_open() == false) { std::cout std::cout std::string body; getContent(&body); std::string buffer = bundle::unpack(body); std::ofstream ofs; ofs.open(filename, std::ios::binary); if(ofs.is_open() == false) { std::cout std::cout public: static bool Serialize(const Json::Value &root, std::string *str) { Json::StreamWriterBuilder swb; std::unique_ptr std::cout Json::CharReaderBuilder crb; std::unique_ptr std::cout #define CONFIG_FILE "./cloud.conf" class Config { private: Config() { ReadConfigFile(); } bool ReadConfigFile() { fileUtil fu(CONFIG_FILE); std::string body; bool ret = fu.getContent(&body); if(ret == false) { std::cout std::cout if(_instance == nullptr) { _mtx.lock(); if(_instance == nullptr) { _instance = new Config(); } _mtx.unlock(); } return _instance; } int getHotTime() { return _hot_time; } int getServerPort() { return _server_port; } std::string getServerIp() { return _server_ip; } std::string getDownloadPrefix() { return _download_prefix; } std::string getPackfileSuffix() { return _packfile_suffix; } std::string getPackDir() { return _pack_dir; } std::string getBackDir() { return _back_dir; } std::string getBackupFile() { return _backup_file; } private: static Config* _instance; static std::mutex _mtx; private: int _hot_time; int _server_port; std::string _server_ip; std::string _download_prefix; std::string _packfile_suffix; std::string _pack_dir; std::string _back_dir; std::string _backup_file; }; Config* Config::_instance = nullptr; std::mutex Config::_mtx; } // namespace cloud class HotManager { private: //非热点文件返回否, 热点文件返回真 bool hotJuge(const std::string& filename) { fileUtil fu(filename); time_t last_atime = fu.lastAccessTime(); time_t cur_time = time(nullptr); if(cur_time - last_atime _hot_time) { return false; } return true; } public: HotManager() { Config* f = Config::getIstance(); _back_dir = f-getBackDir(); _pack_dir = f-getPackDir(); _packfile_suffix = f-getPackfileSuffix(); _hot_time = f-getHotTime(); fileUtil fu1(_back_dir); fileUtil fu2(_pack_dir); fu1.createDirectory(); fu2.createDirectory(); } bool runMoudle() { while(true) { //std::cout if(hotJuge(e)) { continue; } BackupInfo info; bool ret = _data-getBifoByRealPath(e, &info); if(ret == false) { std::cout 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; bool NewBackupInfo(const std::string& filepath) { //std::cout std::cout public: dataManager() { _backup_file = Config::getIstance()-getBackupFile(); pthread_rwlock_init(&_rwlock, nullptr); initLoad(); } bool initLoad()//初始化程序运行时从文件读取数据 { fileUtil fu(_backup_file); if(fu.exists() == false) { return true; } std::string body; bool ret = fu.getContent(&body); if(ret == false) { std::cout std::cout 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; } bool storage() //每次有信息改变则需要持久化存储一次 { 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); } std::string body; bool ret = JsonUtil::Serialize(root, &body); if(ret == false) { std::cout std::cout 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 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; } 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; } bool getAll(std::vector pthread_rwlock_wrlock(&_rwlock); for(auto& e : _table) { arry-push_back(e.second); } pthread_rwlock_unlock(&_rwlock); return true; } ~dataManager() { pthread_rwlock_destroy(&_rwlock); } private: std::string _backup_file; pthread_rwlock_t _rwlock; std::unordered_map class serevr { private: static void upLoad(const httplib::Request& rq, const httplib::Response& rp) { bool ret = rq.has_file("file"); if(ret == false) { return ; } const auto& file = rq.get_file_value("file"); std::string real_path = _back_dir + fileUtil(file.filename).fileName(); fileUtil fu(real_path); fu.setContent(file.content); BackupInfo info; info.NewBackupInfo(real_path); _data-insert(info); return; } static std::string timeToString(time_t t) { return std::ctime(&t); } static void listShow(const httplib::Request& rq, httplib::Response& rp) { std::vector ss
文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。