云备份——实用类工具实现

一,文件实用类设计实现

不管是客户端还是服务端,文件的传输备份都涉及到文件的读写,包括数据管理信息的持久化也是如此,因此首先设计封装文件操作类,这个类封装完毕之后,则在任意模块中对文件进行操作时都将变的简单化。

我们对文件的操作主要有以下几种,也就是我们文件实用类需要实现的功能

  • 获取文件大小
  • 获取文件最后一次修改时间(客户端在判断文件是否需要上传时需要用到)
  • 获取文件最后一次访问时间(判断文件是否属于热点文件就是通过最后一次访问时间)
  • 获取文件路径中的文件名
  • 向文件写入数据、获取文件数据
  • 获取文件指定位置,指定长度的数据(断点重传功能的实现需要该接口)
  • 判断文件是否存在
  • 创建文件目录、获取文件目录
  • 压缩文件、解压文件

设计接口如下

class FileUtil
    {
    public:
        //获取文件大小
        size_t size();
        //获取文件最后一次修改时间&最后一次访问时间
        time_t LastMTime();
        time_t LastATime();
        //获取文件路径名中的文件名
        std::string FileName();
        //向文件写入数据&向文件读取数据
        bool SetContent(const std::string& body);
        bool GetContent(std::string* body);
        //获取文件指定位置指定长度字符串
        bool GetPosLen(std::string* body,size_t pos,size_t len);
        //判断文件是否存在
        bool Exists();
        //创建文件目录&获取文件目录
        bool CreateDirectory();
        bool GetDirectory();
        //压缩文件&解压文件
        bool Compress(const std::string& packname);
        bool UnCompress(const std::string& filename);

    private:
        std::string _filename;
    };

代码实现如下

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()
        {
            int pos=_filename.find_last_of("/");
            if(pos<0)
            {
                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 0;
            }
            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()
        {
            // ./abc/ab/c.txt
                if(_filename.empty()) return false;
                if(exists(_filename)) return false;
                int pos=0,indox=0;

                while(indox<_filename.size())
                {
                    pos=_filename.find_first_of("/\\",indox);
                    

                    //当pos==npos时,说明pos到indox已经没有/,说该创建最后一个文件,创建完break即可
                    if(pos==std::string::npos)
                    {
                        mkdir(_filename.c_str(),0777);
                        break;
                    }
                    if(!exists(_filename.substr(0,pos))) mkdir(_filename.substr(0,pos).c_str(),0777);
                    indox=pos+1;
                }
                return true;
        }
        bool GetDirectory(std::string* filepath)
        {
            if(_filename.empty()) return false;
                int pos=_filename.find_last_of("/\\");
                if(pos==std::string::npos)//pos==npos说明没有找到
                {
                    return false;
                }
                *filepath=_filename.substr(0,pos+1);
                return true;
        }
        //压缩文件&解压文件
        bool Compress(const std::string& packname)
        {
            //1.读取文件内容
            std::string filebody;
            if(GetContent(&filebody)==false)
            {
                std::cout<<"get file body failed"<<std::endl;
                return false;
            }
            //2.压缩获取的内容
            std::string packbody;
            packbody=bundle::pack(bundle::LZIP,filebody);
            //3.将压缩的数据放到压缩包文件中
            FileUtil fu(packname);
            if(fu.SetContent(packbody)==false)
            {
                std::cout<<"compress write failed"<<std::endl;
                return false;
            }
            return true;
        }
        bool UnCompress(const std::string& filename)
        {
            //1.读取压缩文件内容
            std::string packbody;
            if(GetContent(&packbody)==false)
            {
                std::cout<<"get pack file body failed"<<std::endl;
                return false;
            }
            //2.解压读到的内容
            std::string filebody;
            filebody=bundle::unpack(packbody);
            //3.将解压后的内容放入文件中
            FileUtil fu(filename);
            if(fu.SetContent(filebody)==false)
            {
                std::cout<<"file write failed"<<std::endl;
                return false;
            }
            return true;
        }
    private:
        //用于类内使用
        bool exists(const std::string& filename)
        {
            struct stat sm;
            return stat(filename.c_str(),&sm)==0;
        }
    private:
        std::string _filename;
    };

测试代码

#include "util.hpp"

int main()
{
    //测试大小,最后修改时间,最后访问时间
    mjw_cloud::FileUtil fu("./test1.txt");
    std::cout<<fu.FileSize()<<std::endl;
    std::cout<<fu.LastMTime()<<std::endl;
    std::cout<<fu.LastATime()<<std::endl;
    std::cout<<"--------------------------------------"<<std::endl;

    //测试获取文件名,文件写入,文件读取
    std::cout<<fu.FileName()<<std::endl;
    std::string write("hello,word\n");
    std::cout<<write<<":";
    fu.SetContent(write);
    std::string read;
    fu.GetContent(&read);
    std::cout<<read<<std::endl;
    std::cout<<"--------------------------------------"<<std::endl;

    //压缩文件,解压文件
    fu.Compress("./test1.lzip");
    std::cout<<"压缩成功\n"<<std::endl;
    fu.UnCompress("./test1_lzip.txt");
    std::cout<<"解压成功\n"<<std::endl;

    std::cout<<"--------------------------------------"<<std::endl;

    //创建目录.获取文件目录
    mjw_cloud::FileUtil ex("./a/b/c");
    ex.CreateDirectory();
    std::string filepath;
    ex.GetDirectory(&filepath);
    std::cout<<filepath<<std::endl;

    std::cout<<"--------------------------------------"<<std::endl;
    return 0;
}

结果如下

二,Json实用类实现

该类主要是对Json序列化反序列化的通用代码进行一个封装,减少重复代码的实用

 

/*util.hpp*/
    class JsonUtil
    {
    public:
        static bool Serialize(const Json::Value &root, std::string *str)
        {
            Json::StreamWriterBuilder swb;
            std::shared_ptr<Json::StreamWriter> writer_ptr(swb.newStreamWriter());
            std::ostringstream sst;
            writer_ptr->write(root, &sst);
            *str = sst.str();
            return true;
        }
        static bool UnSerialize(const std::string &str, Json::Value *root)
        {
            std::string err;
            Json::CharReaderBuilder crb;
            std::shared_ptr<Json::CharReader> read_ptr(crb.newCharReader());
            read_ptr->parse(str.c_str(), str.c_str() + str.size(), root, &err);
            return true;
        }
    };

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/100519.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

leetcode 155.最小栈

⭐️ 题目描述 &#x1f31f; leetcode链接&#xff1a;https://leetcode.cn/problems/min-stack/description/ 思路&#xff1a; 准备两个栈&#xff0c;一个存放数据的栈&#xff0c;一个最小栈&#xff08;依次存放最小值&#xff09;。存放数组的栈 push 、top 、pop 都是…

ClickHouse进阶(五):副本与分片-1-副本与分片

进入正文前&#xff0c;感谢宝子们订阅专题、点赞、评论、收藏&#xff01;关注IT贫道&#xff0c;获取高质量博客内容&#xff01; &#x1f3e1;个人主页&#xff1a;含各种IT体系技术,IT贫道_Apache Doris,大数据OLAP体系技术栈,Kerberos安全认证-CSDN博客 &#x1f4cc;订阅…

CF Edu152 C

Problem - C - Codeforces 题意&#xff1a; 思路&#xff1a; 首先&#xff0c;观察样例可知 这种是等效的 推广一下 0000.....111111 ..l..............r...... 这种是等效的 容易想到维护后面第一个1的位置和前面第一个0的位置&#xff0c;然后把所有区间都等效一下&…

硬盘数据恢复- 硬盘中文件打开报错的数据恢复案例

硬盘数据恢复环境&故障情况&#xff1a; 某单位重要数据在一台WINDOWS操作系统的PC机上通过网络共享给公司员工使用。这台PC同时也连接着打印机提供打印服务&#xff0c;很多员工直接将文件拷贝到这台PC上进行打印。该PC机上只有一块500G磁盘。 该PC的F盘分区所有类型文件突…

springboot:时间格式化的5种方法(解决后端传给前端的时间格式转换问题)推荐使用第4和第5种!

本文转载自&#xff1a;springboot&#xff1a;时间格式化的5种方法&#xff08;解决后端传给前端的时间显示不一致&#xff09;_为什么前端格式化日期了后端还要格式化_洛泞的博客-CSDN博客 时间问题演示 为了方便演示&#xff0c;我写了一个简单 Spring Boot 项目&#xff…

Spring Boot业务系统如何实现海量数据高效实时搜索

1.概述 我们都知道随着业务系统的发展和使用&#xff0c;数据库存储的业务数据量会越来越大&#xff0c;逐渐成为了业务系统的瓶颈。在阿里巴巴开发手册中也建议&#xff1a;单表行数超过500万行或者单表容量超过2GB才推荐进行分库分表&#xff0c;如果预计三年后数据量根本达…

微服务--服务介绍

Spring Cloud实现对比 Spring Cloud 作为一套标准&#xff0c;实现不一样 Spring Cloud AlibabaSpring Cloud NetflixSpring Cloud 官方Spring Cloud Zookeeper分布式配置Nacos ConficArchaiusSpring Cloud ConfigZookeeper服务注册/发现Nacos DiscoveryEureka--Zookeeper服务…

嵌入式学习笔记(7)ARM汇编指令4-多寄存器指令

多寄存器访问指令 ldr/str每周期只能访问4字节内存&#xff0c;如果需要批量读取、写入内存的话太慢&#xff0c;解决方案就是ldm/stm&#xff0c;ldm(load register multiple)&#xff0c;stm(store register multiple) 举例&#xff1a; stmia sp, {r0 - r12} 将r0存入sp指…

自动驾驶——【规划】记忆泊车特殊学习路径拟合

1.Back ground 如上图&#xff0c;SLAM学习路线Start到End路径&#xff0c;其中曲线SDAB为D档位学习路径&#xff0c;曲线BC为R学习路径&#xff0c;曲线AE为前进档D档学习路径。 为了使其使用记忆泊车时&#xff0c;其驾驶员体验感好&#xff0c;需去除R档倒车部分轨迹&#x…

画流程图都可以用哪些工具?

在日常生活中&#xff0c;我相信我们很多人都看到过流程图。对于设计师来说&#xff0c;它还需要涉及流程图来反映用户的旅程和交互方式。那么你知道哪些流行的流程图设计软件呢&#xff1f;作为高级设计师&#xff0c;我今天推荐10款流程图设计软件。你可以和我一起读这篇文章…

Aidex 移动端快速开发框架# RuoYi-Uniapp项目,uniapp vue app项目跨域问题

参考地址&#xff1a; manifest.json官方配置文档&#xff1a;manifest.json 应用配置 | uni-app官网 Chrome 调试跨域问题解决方案之插件篇&#xff1a; uni-app H5跨域问题解决方案&#xff08;CORS、Cross-Origin&#xff09; - DCloud问答 其实uni-app官方有解决跨域的办…

【C++心愿便利店】No.4---C++初谈类和对象

文章目录 前言一、面向过程和面向对象初步认识二、类的引用三、类的定义四、类的访问限定符及封装五、类的作用域六、类的实例化七、类对象模型八、this指针 前言 &#x1f467;个人主页&#xff1a;小沈YO. &#x1f61a;小编介绍&#xff1a;欢迎来到我的乱七八糟小星球&…

uniapp 配置并使用 VueX

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态&#xff0c;并以相应的规则保证状态以一种可预测的方式发生变化。 uni-app 内置了 VueX 1、创建需要的文件 右键点击 根目录【我的是 uni-shop】&#xff0c;然后新建 目录&a…

OBS Studio 30.0 承诺在 Linux 上支持英特尔 QSV,为 DeckLink 提供 HDR 回放功能

导读OBS Studio 30.0 现已推出公开测试版&#xff0c;承诺为这款广受欢迎的免费开源截屏和流媒体应用程序提供多项令人兴奋的新功能&#xff0c;以及大量其他更改和错误修复。 OBS Studio 30.0 承诺在 Linux 上支持英特尔 QSV&#xff08;快速同步视频&#xff09;、WHIP/WebRT…

对战ChatGPT,创邻科技的Graph+AI会更胜一筹吗?

大模型&#xff08;大规模语言模型&#xff0c;即Large Language Model&#xff09;的应用已经成为千行百业发展的必然。特定领域或行业中经过训练和优化的企业级垂直大模型则成为大模型走下神坛、真正深入场景的关键之路。 但是&#xff0c;企业级垂直大模型在正式落地应用前…

idea --Git Commit Template插件

Git Commit Template是一款免费的IntelliJ IDEA插件&#xff0c;用于提供Git提交模板。该插件可以帮助开发者编写规范的Git提交信息&#xff0c;提高代码管理效率。 首先安装插件&#xff1a; 使用Git Commit Template插件: 注&#xff1a;long description和Breaking changes…

新能源汽车动力总成系统及技术

需要动力系统总成的请联&#xff1a;shbinzer 拆车邦 需要动力系统总成的请联&#xff1a;shbinzer 拆车邦 需要动力系统总成的请联&#xff1a;shbinzer 拆车邦 需要动力系统总成的请联&#xff1a;shbinzer 拆车邦 需要动力系统总成的请联&#xff1a;shbinzer …

卸载Pycharm

1.运行 ‪‪D:\PyCharm 2019.3.3\bin\Uninstall.exe 2.删除相关注册表 删除 HKEY_CURRENT_USER\Environment\PyCharm 文件 删除 HKEY_CURRENT_USER\Software\JavaSoft\Prefs\jetbrains 文件夹 3.删除本地缓存 4.重启

博流RISC-V芯片Eclipse环境搭建

文章目录 1、下载 Eclipse2、导入 bouffalo_sdk3、编译4、烧录5、使用ninja编译 之前编译是通过 VSCode 编译&#xff0c;通过手工输入 make 命令编译&#xff0c;我们也可以通过 Eclipse 可视化 IDE 来编译、烧录。 1、下载 Eclipse 至 Eclipse 官网 https://www.eclipse.org…

下面是实践百度飞桨上面的pm2.5分类项目_logistic regression相关

part1:数据的引入&#xff0c;和前一个linear regression基本是一样 part2:数据解析——也就是数据的“规格化” 首先&#xff0c;打算用dataMat[]和labelMat[]数据存储feature和label&#xff0c;并且文件变量fr 然后&#xff0c;是这个for line in fr.readlines()循环&#…