inux(CentOS)/Windows-C++ 云备份项目(项目文件操作工具类设计,完成项目基本文件操作-读写-压缩-目录操作)

本文主要是介绍inux(CentOS)/Windows-C++ 云备份项目(项目文件操作工具类设计,完成项目基本文件操作-读写-压缩-目录操作),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 1. 项目文件操作工具类设计

1. 项目文件操作工具类设计

根据前面的分析,这个文件类的基本属性如下:

  1. 文件大小信息
  2. 文件最后修改时间
  3. 文件最后一次访问时间,方便文件的热点管理
  4. 文件名称,需要从http 请求行上的uri中获取
  5. 基础文件读写接口 写数据为SetContent,读数据GetContent
  6. 获取文件指定位置,指定长度的数据,使其支持断点续传
  7. 获取文件夹的所有文件名称
  8. 判断文件是否存在方法
  9. 创建目录方法,名称是获取的文件名称
  10. 文件压缩解压缩方法

错误日志函数log.hpp

// 项目错误日志打印
#pragma once
#include <iostream>
#include <stdio.h>
#include <string>
#include <time.h>
#define INFO 1
#define WARNING 2
#define ERROR 3
#define FATAL 4
#define LOG(level, message) Log(#level, message, __FILE__, __LINE__) // #将宏参数转化为字符串// 时间戳转化为时间信息
static std::string convertTimeStamp2TimeStr(time_t timeStamp)
{struct tm *timeinfo = nullptr;char buffer[80];timeinfo = localtime(&timeStamp);strftime(buffer, 80, "%Y-%m-%d %H:%M:%S", timeinfo);// printf("%s\n", buffer);return std::string(buffer);
}// 日志级别+日志信息+时间戳+错误文件名称+错误行数
// 日志级别 INFO,WARNING,ERROR,FATAL
void Log(std::string level, std::string msg, std::string file_name, int line)
{std::cout << "[" << level << "]"<< "[" << convertTimeStamp2TimeStr(time(nullptr)) << "]"<< "[" << msg << "]"<< "[" << file_name << "]"<< "[" << line << "]" << std::endl;
}

文件工具类目录操作方法补充:

c库函数scandir函数:这个函数比较复杂使用这个也可以,这里使用C++17Filesystem类中的方法
在这里插入图片描述
Filesystem library (since C++17)

在这里插入图片描述
在这里插入图片描述
注意使用这个库需要在编译时加上-lstdc++fs

项目文件操作工具类设计:

#pragma once
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <sys/stat.h>
#include "log.hpp"
#include "../bundle/bundle.h"
// #include <filesystem>
#include <experimental/filesystem>
namespace CloudBackups
{namespace fs = std::experimental::filesystem;class FileUtil{private:std::string _filepath; // 文件名称 uri格式struct stat st;        // 文件属性public:FileUtil(const std::string &filepath){_filepath = filepath;if (stat(_filepath.c_str(), &st) < 0){LOG(WARNING, "get file stat failed! maybe this file not exits");}}int64_t filesize() { return st.st_size; }         // 获取文件大小,失败返回-1time_t last_modify_time() { return st.st_mtime; } // 获取文件最后修改时间time_t last_visit_time() { return st.st_atime; }  // 获取文件最后访问时间std::string filename()                            // 文件名称{size_t pos = _filepath.find_last_of("/");if (pos == std::string::npos){return _filepath;}return _filepath.substr(pos + 1);}bool getPoslen(std::string &body, size_t pos, size_t len) // 从文件中读取len个字节,从pos位置开始读取,读取内容放到body中,为了实现断点续传{size_t size = this->filesize(); // 文件大小if (pos >= size){LOG(ERROR, "pos is out of range!");return false;}if (pos + len > size){LOG(ERROR, "pos + len is out of range!");return false;}std::ifstream ifs;ifs.open(_filepath.c_str(), std::ios::binary);if (!ifs.is_open()){LOG(ERROR, "open file failed!");return false;}ifs.seekg(pos, std::ios::beg);body.resize(len);ifs.read(&body[0], len);if (!ifs.good()){// 上次读取出错LOG(ERROR, "read file failed!");ifs.close();return false;}ifs.close();return true;}bool getContent(std::string &body) // 获取整体的文件数据{size_t size = this->filesize();return getPoslen(body, 0, size);}bool setContent(const std::string &body) // 设置文件内容{std::ofstream ofs;ofs.open(_filepath.c_str(), std::ios::binary);if (!ofs.is_open()){LOG(ERROR, "open file failed!");return false;}ofs.write(body.c_str(), body.size());if (!ofs.good()){// 上次写入出错LOG(ERROR, "write file failed!");ofs.close();return false;}ofs.close();return true;}bool zip(const std::string &packname) // 文件压缩功能,传入压缩后名称{// 读取源文件所有内容std::string body;if (this->getContent(body) == false){// 获取源文件数据失败LOG(ERROR, "get file content failed!");return false;}// 对数据进行压缩std::string packed = bundle::pack(bundle::LZIP, body);// 保存压缩后的数据FileUtil file(packname);if (file.setContent(packed) == false){ // 保存压缩后的数据失败LOG(ERROR, "save zip file content failed!");return false;}return true;}bool unzip(const std::string &filename) // 文件解压缩功能,传入解压缩文件名称{// 读取当前压缩的数据std::string body;if (this->getContent(body) == false){// 获取源文件数据失败LOG(ERROR, "get zip file content failed!");return false;}// 对压缩的数据进行解压std::string unpacked = bundle::unpack(body);// 保存解压数据FileUtil file(filename);if (file.setContent(unpacked) == false){ // 保存解压数据失败LOG(ERROR, "save unzip file content failed!");return false;}return true;}bool isExit() { return fs::exists(_filepath); } // 判断文件是否存在bool mkdir()                                    // 创建文件夹{if (this->isExit()){return true;}return fs::create_directories(_filepath);}bool ls(std::vector<std::string> &files) // 扫描文件夹,并返回里面的文件{for (auto &pos : fs::directory_iterator(_filepath)){if (fs::is_directory(pos) == true){continue; // 目录不出来}files.push_back(fs::path(pos).relative_path().string()); // 获取文件的相对路径}return true;}};
}

在这里插入图片描述
在这里插入图片描述

根据上图可知,项目文件属性获取,文件读写,文件压缩与解压缩基本功能没有问题

代码位置:
Gitee地址
Gitee地址

这篇关于inux(CentOS)/Windows-C++ 云备份项目(项目文件操作工具类设计,完成项目基本文件操作-读写-压缩-目录操作)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/816762

相关文章

C++实现回文串判断的两种高效方法

《C++实现回文串判断的两种高效方法》文章介绍了两种判断回文串的方法:解法一通过创建新字符串来处理,解法二在原字符串上直接筛选判断,两种方法都使用了双指针法,文中通过代码示例讲解的非常详细,需要的朋友... 目录一、问题描述示例二、解法一:将字母数字连接到新的 string思路代码实现代码解释复杂度分析三、

mysql8.0无备份通过idb文件恢复数据的方法、idb文件修复和tablespace id不一致处理

《mysql8.0无备份通过idb文件恢复数据的方法、idb文件修复和tablespaceid不一致处理》文章描述了公司服务器断电后数据库故障的过程,作者通过查看错误日志、重新初始化数据目录、恢复备... 周末突然接到一位一年多没联系的妹妹打来电话,“刘哥,快来救救我”,我脑海瞬间冒出妙瓦底,电信火苲马扁.

Java中有什么工具可以进行代码反编译详解

《Java中有什么工具可以进行代码反编译详解》:本文主要介绍Java中有什么工具可以进行代码反编译的相关资,料,包括JD-GUI、CFR、Procyon、Fernflower、Javap、Byte... 目录1.JD-GUI2.CFR3.Procyon Decompiler4.Fernflower5.Jav

Vue项目的甘特图组件之dhtmlx-gantt使用教程和实现效果展示(推荐)

《Vue项目的甘特图组件之dhtmlx-gantt使用教程和实现效果展示(推荐)》文章介绍了如何使用dhtmlx-gantt组件来实现公司的甘特图需求,并提供了一个简单的Vue组件示例,文章还分享了一... 目录一、首先 npm 安装插件二、创建一个vue组件三、业务页面内 引用自定义组件:四、dhtmlx

使用Python创建一个能够筛选文件的PDF合并工具

《使用Python创建一个能够筛选文件的PDF合并工具》这篇文章主要为大家详细介绍了如何使用Python创建一个能够筛选文件的PDF合并工具,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下... 目录背景主要功能全部代码代码解析1. 初始化 wx.Frame 窗口2. 创建工具栏3. 创建布局和界面控件4

Docker部署Jenkins持续集成(CI)工具的实现

《Docker部署Jenkins持续集成(CI)工具的实现》Jenkins是一个流行的开源自动化工具,广泛应用于持续集成(CI)和持续交付(CD)的环境中,本文介绍了使用Docker部署Jenkins... 目录前言一、准备工作二、设置变量和目录结构三、配置 docker 权限和网络四、启动 Jenkins

SpringBoot项目注入 traceId 追踪整个请求的日志链路(过程详解)

《SpringBoot项目注入traceId追踪整个请求的日志链路(过程详解)》本文介绍了如何在单体SpringBoot项目中通过手动实现过滤器或拦截器来注入traceId,以追踪整个请求的日志链... SpringBoot项目注入 traceId 来追踪整个请求的日志链路,有了 traceId, 我们在排

Python中多线程和多进程的基本用法详解

《Python中多线程和多进程的基本用法详解》这篇文章介绍了Python中多线程和多进程的相关知识,包括并发编程的优势,多线程和多进程的概念、适用场景、示例代码,线程池和进程池的使用,以及如何选择合适... 目录引言一、并发编程的主要优势二、python的多线程(Threading)1. 什么是多线程?2.

MobaXterm远程登录工具功能与应用小结

《MobaXterm远程登录工具功能与应用小结》MobaXterm是一款功能强大的远程终端软件,主要支持SSH登录,拥有多种远程协议,实现跨平台访问,它包括多会话管理、本地命令行执行、图形化界面集成和... 目录1. 远程终端软件概述1.1 远程终端软件的定义与用途1.2 远程终端软件的关键特性2. 支持的

C++一个数组赋值给另一个数组方式

《C++一个数组赋值给另一个数组方式》文章介绍了三种在C++中将一个数组赋值给另一个数组的方法:使用循环逐个元素赋值、使用标准库函数std::copy或std::memcpy以及使用标准库容器,每种方... 目录C++一个数组赋值给另一个数组循环遍历赋值使用标准库中的函数 std::copy 或 std::