util工具
fileUtil(文件操作类)
在客户端,又或者是在服务端,本质是都是对文件的读写和管理,所以有必要封装一个文件操作类。
class FileUtil{ private: std::string _name; public: FileUtil(const std::string &name); size_t FileSize();// 文件大小 time_t LastATime(); // 最后一次查看文件时间 time_t LastMTime(); // 最后一次修改文件的时间 std::string FileName(); //文件名字 bool GetPosLen(std::string *content, size_t pos, size_t len); //获取文件流pos 后len个长度的数据 bool GetContent(std::string *content); //获取文件内容 bool SetContent(std::strint *content); //写入文件 bool Compress(const std::string &packname); //压缩文件 bool UnCompress(const std::string &filename); //解压文件 bool Exists(); //判断文件是否存在 bool CreateDirectory(); //创建一个目录 bool ScanDirectory(std::vector<std::string> *arry); //查看目录下的文件内容 }
JsonUtil
服务端和客户端进行对话,传输数据,一定要跨网络传输,就一定需要将数据序列化(Serialize)和反序列化(UnSerialize)。
class JsonUtil{ public: static bool Serialize(const Json::Value &root, std::string *str); //序列化 static bool UnSerialize(const std::string &str, Json::Value *root); //反序列化 };
注意:
编译时,我们需要链接第三方库
-lpthread -lstdc++fs -ljsoncpp -lbundle
-lpthread ,-lbundle: bundle.h中调用了线程库,所以需要链接。
-lstdc++fs : 文件中关于目录部分的函数编写调用了filesystem中的函数。
-ljsoncpp :序列和反序列化时需要。
代码:
#include <iostream> #include <fstream> #include <string> #include <vector> #include <experimental/filesystem> #include <sys/stat.h> #include <jsoncpp/json/json.h> #include "bundle.h" namespace cloud{ namespace fs = std::experimental::filesystem; class FileUtil{ private: std::string _filename; public: FileUtil(const std::string &filename):_filename(filename){} bool Remove(){ if (this->Exists()== false) { return true; } remove(_filename.c_str()); return true; } int64_t FileSize(){ struct stat st; if (stat(_filename.c_str(), &st) < 0) { std::cout << "get file size failed!\n"; return -1; } return st.st_size; } time_t LastMTime(){ struct stat st; if (stat(_filename.c_str(), &st) < 0) { std::cout << "get file size failed!\n"; return -1; } return st.st_mtime; } time_t LastATime() { struct stat st; if (stat(_filename.c_str(), &st) < 0) { std::cout << "get file size failed!\n"; return -1; } return st.st_atime; } std::string FileName(){ // ./abc/test.txt size_t pos = _filename.find_last_of("/"); if (pos == std::string::npos) { return _filename; } return _filename.substr(pos+1); } bool GetPosLen(std::string *body, size_t pos, size_t len){ size_t fsize = this->FileSize(); if (pos + len > fsize){ std::cout << "get file len is error\n"; return false; } std::ifstream ifs; ifs.open(_filename, std::ios::binary); if (ifs.is_open() == false) { std::cout << "read open file failed!\n"; return false; } ifs.seekg(pos, std::ios::beg); body->resize(len); ifs.read(&(*body)[0], len); if (ifs.good() == false) { std::cout << "get file content failed\n"; ifs.close(); return false; } ifs.close(); return true; } bool GetContent(std::string *body) { size_t fsize = this->FileSize(); return GetPosLen(body, 0, fsize); } bool SetContent(const std::string &body) { std::ofstream ofs; ofs.open(_filename, std::ios::binary); if (ofs.is_open() == false) { std::cout << "write open file failed!\n"; return false; } ofs.write(&body[0], body.size()); if (ofs.good() == false) { std::cout << "write file content failed!\n"; ofs.close(); return false; } ofs.close(); return true; } bool Compress(const std::string &packname){ //1. 获取源文件数据 std::string body; if (this->GetContent(&body) == false){ std::cout << "compress get file content failed!\n"; return false; } //2. 对数据进行压缩 std::string packed = bundle::pack(bundle::LZIP, body); //3. 将压缩的数据存储到压缩包文件中 FileUtil fu(packname); if (fu.SetContent(packed) == false){ std::cout << "compress write packed data failed!\n"; return false; } return true; } bool UnCompress(const std::string &filename) { //将当前压缩包数据读取出来 std::string body; if (this->GetContent(&body) == false){ std::cout << "uncompress get file content failed!\n"; return false; } //对压缩的数据进行解压缩 std::string unpacked = bundle::unpack(body); //将解压缩的数据写入到新文件 FileUtil fu(filename); if (fu.SetContent(unpacked) == false){ std::cout << "uncompress write packed data failed!\n"; return false; } return true; } bool Exists() { return fs::exists(_filename); } bool CreateDirectory() { if (this->Exists()) return true; return fs::create_directories(_filename); } bool ScanDirectory(std::vector<std::string> *arry) { for(auto& p: fs::directory_iterator(_filename)) { if (fs::is_directory(p) == true){ continue; } //relative_path 带有路径的文件名 arry->push_back(fs::path(p).relative_path().string()); } return true; } }; class JsonUtil{ public: static bool Serialize(const Json::Value &root, std::string *str){ Json::StreamWriterBuilder swb; std::unique_ptr<Json::StreamWriter> sw(swb.newStreamWriter()); std::stringstream ss; if (sw->write(root, &ss) != 0) { std::cout << "json write failed!\n"; return false; } *str = ss.str(); return true; } static bool UnSerialize(const std::string &str, Json::Value *root){ Json::CharReaderBuilder crb; std::unique_ptr<Json::CharReader> cr(crb.newCharReader()); std::string err; bool ret = cr->parse(str.c_str(), str.c_str() + str.size(), root, &err); if (ret == false) { std::cout << "parse error: " << err << std::endl; return false; } return true; } }; }