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地址

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

P8780 [蓝桥杯 2022 省 B] 刷题统计 Python

[蓝桥杯 2022 省 B] 刷题统计 题目描述 小明决定从下周一开始努力刷题准备蓝桥杯竞赛。他计划周一至周五每天做 a a a 道题目&#xff0c;周六和周日每天做 b b b 道题目。请你帮小明计算&#xff0c;按照计划他将在第几天实现做题数大于等于 n n n 题? 输入格式 输入一…

JavaWeb(p135-p155)

分页查询 可以利用分页插件PageHelper 1.引入依赖 <dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper-spring-boot-starter</artifactId><version>1.4.2</version> </dependency>2.EmpMapper …

Python 数据结构与算法

Python 是一种强大且灵活的编程语言&#xff0c;非常适合用于实现各种数据结构和算法。数据结构和算法是计算机科学中的基础概念&#xff0c;对于解决实际问题、优化程序性能以及提高代码的可读性和可维护性至关重要。 ### 数据结构 数据结构是计算机存储、组织和管理数据的方…

Linux系统——Session ID(负载均衡如何保持会话)

目录 一、实验环境搭建 二、部署Nginx代理服务器配置 三、部署后端真是服务器Tomcat配置 四、配置Tomcat的Session ID会话保持 五、测试 此次实验是Tomcat后端服务器如何做Session ID会话保持 一、实验环境搭建 [rootlocalhost ~]#systemctl stop firewalld [rootlocalho…

一起学数据分析_3(模型建立与评估_2)

为什么要评估? 在进行数据分析时&#xff0c;尤其是在使用像sklearn这样的机器学习库建立模型后&#xff0c;模型评估的重要性不言而喻。模型评估不仅是对模型性能的一次全面检验&#xff0c;更是确保模型在实际应用中能够达到预期效果的关键步骤。 首先&#xff0c;模型评估…

iguana 库 C++ 反射原理

iguana Github : https://github.com/fananchong/iguana 官方介绍&#xff1a; universal serialization engine 虽然官方介绍是通用的序列化引擎&#xff0c;但实际上目前只支持&#xff1a; jsonyamlxml 不过&#xff0c; C 结构体/类的反射部分是通用的 通过该库&…

Linux 自动备份 mysql 脚本

这个脚本会将数据库备份为一个SQL文件&#xff0c;并将其保存在指定的目录中。 #!/bin/bash# MySQL配置 DB_USER"your_mysql_username" DB_PASS"your_mysql_password" DB_NAME"your_database_name" DB_HOST"localhost"# 备份目录 BAC…

Spring核心方法:Refresh全解(WebMVC如何装配、关联)

Spring核心方法&#xff1a;Refresh全解(WebMVC如何装配、关联) 这里是一个表格&#xff0c;列出了Spring容器刷新过程中执行的方法以及它们的作用&#xff1a; 方法名称描述prepareRefresh()初始化一些属性和状态&#xff0c;例如启动时间戳、活动标志、环境变量等。obtainF…

HTML-DAY2

HTML-DAY2 表格标签 表格的主要作用 表格主要用于显示、展示数据&#xff0c;因为它可以让数据显示的非常的规整&#xff0c;可读性非常好。特别是后台展示数据的时候&#xff0c;能够熟练运用表格就显得很重要。一个清爽简约的表格能够把繁杂的数据表现得很有条理。 Pink老…

Python的Selenium库中的模块、类和异常的汇总

这些是 Selenium Python 库中的模块、类和异常&#xff0c;用于实现自动化 Web 浏览器测试和网页操作。以下是它们的简单解释&#xff1a;Python Module Index — Selenium 4.18.1 documentation 1. selenium.common.exceptions&#xff1a;包含了 Selenium 中可能出现的异常。…

一款比 K8S 更好用的编排工具——Nomod

今天给笔友们推荐一款最近发现的服务编排工具Nomad。综合感觉就是功能很强大&#xff0c;姿势很优雅&#xff0c;相比 K8S 更加轻量级&#xff0c;相比 Docker-Compose 能轻松支持分布式。 Nomad 能做什么&#xff1f; Nomad 采用统一的工作流程&#xff0c;既可以轻松部署和管…

python自动化之(django)(2)

1、创建应用 python manage.py startapp apitest 这里还是从上节开始也就是命令行在所谓的autotest目录下来输入 然后可以清楚的看到 多了一个文件夹 2、创建视图 在views中加入test函数&#xff08;所建应用下&#xff09; from django.http import HttpResponse def tes…

C/C++蓝桥杯之卡片问题

问题描述&#xff1a;小兰有很多数字卡片&#xff0c;每张卡片上都是数字0&#xff5e;9。 小兰&#xff0c;准备用这些卡片拼一些数。她想从1开始拼出正整数&#xff0c;每拼一个就保存起来&#xff0c;卡片就不能再用来拼其他数了。 小兰想知道自己能从1拼到多少。 例如&a…

在Swift中集成Socket.IO进行实时通信

在Swift中集成Socket.IO进行实时通信 实时通信是许多现代应用程序的重要组成部分&#xff0c;从聊天应用程序到协作平台。Socket.IO 是一个流行的库&#xff0c;用于在 Web 和移动应用程序中实现实时的双向通信。在本文中&#xff0c;我们将讨论如何使用 Socket.IO-Client-Swi…

Rust的所有权和生命周期机制的本质

目录 所有权机制生命周期机制Rust的堆和栈堆和栈内存分配方式内存管理方式内存分配速度内存大小限制 Rust的所有权和生命周期机制的本质是关于数据在堆和栈中的存储方式。这两个概念是为了解决内存管理和资源分配的问题。 所有权机制 所有权机制确保每个值都有唯一的所有者&a…

基于CNN多阶段图像超分+去噪(超级简单版)

这是之前的一项工作&#xff0c;非常简单&#xff0c;简单的复现了两个算法&#xff0c;然后把它们串起来了。 可执行的程序链接&#xff1a;CSDN; Github 我们分成两部分进行讲解&#xff1a; 1. 图像去噪 1.1 基本思路 图像的去噪工作基于很普通的CNN去噪&#xff0c;效…

Swift 面试题及答案整理,最新面试题

Swift 中如何实现单例模式&#xff1f; 在Swift中&#xff0c;单例模式的实现通常采用静态属性和私有初始化方法来确保一个类仅有一个实例。具体做法是&#xff1a;定义一个静态属性来存储这个单例实例&#xff0c;然后将类的初始化方法设为私有&#xff0c;以阻止外部通过构造…

Ubuntu Desktop - gnome-calculator (计算器)

Ubuntu Desktop - gnome-calculator [计算器] 1. Ubuntu Software -> gnome-calculator -> Install -> Continue2. Search your computer -> Calculator -> Lock to LauncherReferences 1. Ubuntu Software -> gnome-calculator -> Install -> Continu…

STM32中MicroLIB的关闭为什么会导致卡死----解析

STM32MicroLIB 大家好我是 MHZ 。最近又开始往回捡单片机的知识了~ 之前大学的时候都没用过 STM 的 CubeMX&#xff0c;这会拿来用着感觉很方便啊~ 果然科技在进步&#xff01; 在开发使用 Keil 对 STM32 进行开发的时候在会有一个叫做 MicroLIB 的选项。 这个的具体原因我搜…

C语言 内存函数

目录 前言 一、memcpy()函数 二、memmove()函数 三、memset函数 四、memcmp()函数 总结 前言 在C语言中内存是我们用来存储数据的地址&#xff0c;今天我们来讲一下C语言中常用的内存函数。 一、memcpy()函数 memcpy()函数与我们之前讲的strcpy()函数类似&#xff0c;只…