云备份客户端——客户端整体设计框架以及实用类工具实现

 一,客户端整体框架

客户端要实现的功能和服务端相比相对简单,客户端要实现的功能是自动对指定文件中的文件进行备份,也就是定时对指定文件进行扫描,根据文件信息判断文件,符合要求(新文件或者被修改过的文件)进行上传

因此我们客户端大概需要实现下面三个模块

  • 数据管理模块:管理备份文件的文件信息,后续需要通过该信息判断文件是否上传
  • 目录遍历模块:定时遍历指定文件下的所有文件
  • 文件备份模块:遍历文件时,根据文件信息判断是否上传

 开发环境

 由于我们客户端大多是给windows用户使用的,因此客户端在Windows上用vs2019进行开发

二,实用工具类实现

客户端的实用工具类的实现和服务端是一样的,但是功能少了些,例如压缩解压缩,同时因为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;
        }

        // 创建文件目录&获取文件目录
        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

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值