?一,客戶端整體框架
客戶端要實現的功能和服務端相比相對簡單,客戶端要實現的功能是自動對指定文件中的文件進行備份,也就是定時對指定文件進行掃描,根據文件信息判斷文件,符合要求(新文件或者被修改過的文件)進行上傳
因此我們客戶端大概需要實現下面三個模塊
- 數據管理模塊:管理備份文件的文件信息,后續(xù)需要通過該信息判斷文件是否上傳
- 目錄遍歷模塊:定時遍歷指定文件下的所有文件
- 文件備份模塊:遍歷文件時,根據文件信息判斷是否上傳
?開發(fā)環(huán)境
?由于我們客戶端大多是給windows用戶使用的,因此客戶端在Windows上用vs2019進行開發(fā)
二,實用工具類實現
客戶端的實用工具類的實現和服務端是一樣的,但是功能少了些,例如壓縮解壓縮,同時因為vs2019上按照Json庫不太方便,因此Json序列化和Json反序列化也不在使用,而在數據管理模塊中數據存儲時用到的序列化和反序列化,由我們自己完成。
#ifndef _MY_UTIL_
#define _MY_UTIL_
#define _SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING 1
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <memory>
#include <sstream>
#include <experimental/filesystem>
#include <sys/stat.h>
namespace mjw_cloud
{
namespace fs=std::experimental::filesystem;
class FileUtil
{
public:
FileUtil(const std::string &filename)
: _filename(filename)
{
}
// 獲取文件大小
size_t FileSize()
{
struct stat st;
if (stat(_filename.c_str(), &st) < 0)
{
std::cout << "get file attributes failed" << std::endl;
return -1;
}
return st.st_size;
}
// 獲取文件最后一次修改時間&最后一次訪問時間
time_t LastMTime()
{
struct stat st;
if (stat(_filename.c_str(), &st) < 0)
{
std::cout << "get file attributes failed" << std::endl;
return -1;
}
return st.st_mtime;
}
time_t LastATime()
{
struct stat st;
if (stat(_filename.c_str(), &st) < 0)
{
std::cout << "get file attributes failed" << std::endl;
return -1;
}
return st.st_atime;
}
// 獲取文件路徑名中的文件名
//./abc/test.c ->test.c
std::string FileName()
{
//這里由于時Windows下,因此目錄符號需要改變
/*int pos = _filename.find_last_of("/");*/
int pos = _filename.find_last_of("\\");
if (pos < 0)
{
if(!_filename.empty()) return _filename;
std::cout << "filename error" << std::endl;
return nullptr;
}
return _filename.substr(pos + 1);
}
// 獲取文件指定位置指定長度字符串
bool GetPosLen(std::string *body, size_t pos, size_t len)
{
std::ifstream ifs(_filename, std::ios::binary);
if (ifs.is_open() == false)
{
std::cout << "open file failed" << std::endl;
return false;
}
size_t size = this->FileSize();
if (pos + len > size)
{
std::cout << "Get filecontent is be illegal" << std::endl;
return false;
}
ifs.seekg(pos, ifs.beg);
body->resize(size);
ifs.read(&(*body)[0], len);
if (ifs.good() == false)
{
std::cout << "read file failed" << std::endl;
return false;
}
ifs.close();
return true;
}
// 向文件寫入數據&向文件讀取數據
bool SetContent(const std::string &body)
{
std::ofstream ofs(_filename, std::ios::binary);
if (ofs.is_open() == false)
{
std::cout << "SetContent open file failed" << std::endl;
return false;
}
ofs.write(&body[0], body.size());
if (ofs.good() == false)
{
std::cout << "write file failed" << std::endl;
return false;
}
ofs.close();
return true;
}
bool GetContent(std::string *body)
{
size_t fsize = this->FileSize();
return GetPosLen(body, 0, fsize);
}
// 判斷文件是否存在
bool Exists()
{
struct stat sm;
return stat(_filename.c_str(), &sm) == 0;
}
// 創(chuàng)建文件目錄&獲取文件目錄
bool CreateDirectory()
{
if(Exists()) return true;
return fs::create_directories(_filename);
}
bool ScanDirectory(std::vector<std::string>* arry)
{
CreateDirectory();
for (auto &i : fs::directory_iterator(_filename))
{
if(fs::is_directory(i)==true)//如果文件是路徑名則跳過
{
continue;
}
arry->push_back(fs::path(i).relative_path().string());
}
return true;
}
bool Remove()
{
if (Exists() == false)
{
std::cout << "object file unexist" << std::endl;
return false;
}
remove(_filename.c_str());
return true;
}
private:
std::string _filename;
};
}
#endif
?文章來源地址http://www.zghlxwxcb.cn/news/detail-698964.html文章來源:http://www.zghlxwxcb.cn/news/detail-698964.html
?
到了這里,關于云備份客戶端——客戶端整體設計框架以及實用類工具實現的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!