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; }         // 获取文件大小,失败返回-1
        time_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地址

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

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

相关文章

html编辑器

HTML 编辑器推荐 html可以使用记事本编辑 但是更建议使用专业的 HTML 编辑器来编辑 HTML&#xff0c;我在这里给大家推荐几款常用的编辑器&#xff1a; VS Code&#xff1a;https://code.visualstudio.com/WebStorm: https://www.jetbrains.com/webstorm/Notepad: https://no…

【八】【算法分析与设计】双指针(2)

11. 盛最多水的容器 给定一个长度为 n 的整数数组 height 。有 n 条垂线&#xff0c;第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。 找出其中的两条线&#xff0c;使得它们与 x 轴共同构成的容器可以容纳最多的水。 返回容器可以储存的最大水量。 说明&#xff1a;你不能…

pytorch 入门基础知识一(Pytorch 01)

一 深度学习基础相关 深度学习三个主要的方向&#xff1a;计算机视觉&#xff0c;自然语言&#xff0c;语音识别。 机器学习核心组件&#xff1a;1 数据集(data)&#xff0c;2 前向传播的model(net)&#xff0c;3 目标函数(loss)&#xff0c; 4 调整模型参数和优化函数的算法…

Ascend C编程入门课:编程基础与Hello World

Ascend C编程入门课 一、基础概念 1.Ascend C&#xff1a;是昇腾异构计算架构CANN针对算子开发场景推出的编程语言&#xff0c;通过多层接口抽象、自动并行计算、孪生调试等关键技术&#xff0c;极大提高算子开发效率。 2.使用Ascend C自定义开发算子的优势&#xff1a; (1…

Golang协程详解

一.协程的引入 1.通过案例文章引入并发,协程概念 见:[go学习笔记.第十四章.协程和管道] 1.协程的引入,调度模型&#xff0c;协程资源竞争问题 通过上面文章可以总结出Go并发编程原理: 在一个处理进程中通过关键字 go 启用多个协程&#xff0c;然后在不同的协程中完成不同的子任…

【网络编程基础(一)】网络基础和SOCKET

这里写目录标题 1、网络三要素2、IPV4和IPV6区别3、网络交互3.1、交互模型图3.2、基础通信协议3.3、OSI参考模型与TCP/IP参考模型对应关系 4、SOCKET网络套接字4.1、SOCKET分类4.2、基于流式套接字的编程流程4.3、网络通信雏形4.4、socket函数4.4.1、socket函数示例 4.5、bind函…

部署一个本地的ChatGPT(Ollama)

一 下载Ollama Ollama下载地址&#xff1a;https://ollama.com/download 下载完后 二 安装运行 双击下载好的OllamaSetup.exe开发 安装Ollama: 安装完成后&#xff0c;多了一个Ollama的菜单如下图 &#xff1a; Ollama安装好默认是配置开机运行&#xff0c;如果没有运行可以在…

高效使用 JMeter 生成随机数:探索 Random 和 UUID 算法

在压力测试中&#xff0c;经常需要生成随机值来模拟用户行为。JMeter 提供了多种方式来生成随机值&#xff0c;本文来具体介绍一下。 随机数函数 JMeter 提供了多个用于生成随机数的函数&#xff0c;其中最常用的是__Random函数。该函数可以生成一个指定范围内的随机整数或浮…

pytorch 实现线性回归(Pytorch 03)

一 线性回归框架 线性模型的四个模块&#xff1a;训练的数据集&#xff0c;线性模型&#xff0c;损失函数&#xff0c;优化算法。 1.1 数据集 使用房价预测数据集&#xff0c;我们希望根据房屋的面积和房龄等来估算房屋价格。 1.2 线性模型 预测公式&#xff0c; 价格 权重…

智慧公厕建设的重要性

智慧公厕建设一直被视为提升城市管理水平的重要举措。作为一个关键的城市基础设施&#xff0c;智慧公厕不仅可以改善公共卫生管理&#xff0c;还能提升城市居民的社会民生生活质量。此外&#xff0c;智慧公厕建设还能促进城市的可持续发展&#xff0c;降低能源消耗&#xff0c;…

rust学习笔记(1-7)

原文 8万字带你入门Rust 1.包管理工具Cargo 新建项目 1&#xff09;打开 cmd 输入命令查看 cargo 版本 cargo --version2&#xff09; 使用 cargo new 项目名 在文件夹&#xff0c;按 shift 鼠标右键 &#xff0c;打开命令行&#xff0c;运行如下命令&#xff0c;即可创建…

【SQL】1193. 每月交易 I 【年月日(日期)拼接相关函数】

前述 知识点学习&#xff1a; SQL 日期函数 day() 、month()、year() 各种使用方法mysql 两个字符年月拼接 题目描述 leetcode题目&#xff1a;1193. 每月交易 I 思路 先按照年月排&#xff0c;再按照country排列 日期拼接相关的函数 year(): 截取年份&#xff1b;month…

linuxOPS基础_linux命令合集

uname查看操作系统信息 命令&#xff1a;uname [参数] 作用&#xff1a;获取计算机操作系统相关信息 参数&#xff1a;-a&#xff0c;选项-a代表all&#xff0c;表示获取全部的系统信息&#xff08;类型、全部主机名、内核版本、发布时间、开源计划&#xff09; 用法一&…

将OpenCV与gcc和CMake结合使用

返回&#xff1a;OpenCV系列文章目录&#xff08;持续更新中......&#xff09; 上一篇&#xff1a;OpenCV4.9.0开源计算机视觉库在 Linux 中安装 下一篇&#xff1a; 引言&#xff1a; 近年来&#xff0c;计算机视觉技术在图像处理、目标检测和机器人等方面得到了广泛的应用…

基于FPGA的光纤通信系统设计

文章目录 光纤通信系统的组成发送端FPGA端口定义状态机设计代码示例 接收端功能模块端口定义状态机设计 光纤通信系统的组成 发送端FPGA 发送控制逻辑、数据编码、校验码生成、缓存控制、时钟控制 端口定义 状态机设计 代码示例 接收端功能模块 接收端控制逻辑、数据解码、…

前世档案(不用二叉树语法秒杀版c++)

网络世界中时常会遇到这类滑稽的算命小程序&#xff0c;实现原理很简单&#xff0c;随便设计几个问题&#xff0c;根据玩家对每个问题的回答选择一条判断树中的路径&#xff08;如下图所示&#xff09;&#xff0c;结论就是路径终点对应的那个结点。 现在我们把结论从左到右顺序…

综合知识篇06-软件架构设计考点(2024年软考高级系统架构设计师冲刺知识点总结系列文章)

专栏系列文章: 2024高级系统架构设计师备考资料(高频考点&真题&经验)https://blog.csdn.net/seeker1994/category_12593400.html案例分析篇00-【历年案例分析真题考点汇总】与【专栏文章案例分析高频考点目录】(2024年软考高级系统架构设计师冲刺知识点总结-案例…

javaEE——线程的等待和结束

文章目录 Thread 类及常见方法启动一个线程中断一个线程变量型中断调用 interrupt() 方法来通知观察标志位是否被清除 等待一个线程获取当前线程引用休眠当前线程 线程的状态观察线程的所有状态观察 1: 关注 NEW 、 RUNNABLE 、 TERMINATED 状态的切换 多线程带来的风险为什么会…

java serlvet 高校学生画像平台系统Myeclipse开发mysql数据库web结构java编程计算机网页项目echarts图形展现

一、源码特点 java serlvet 高校学生画像平台系统是一套完善的java web信息管理系统 系统采用serlvetdaobean 模式开发本系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为TOMCA…

Selenium基础

1. selenium简介 用于实现自动化测试的 python 包&#xff0c;使用前需要安装对应浏览器驱动 from time import sleep from selenium import webdriver option webdriver.ChromeOptions() # 指定chrome存储路径的二进制形式 option.binary_locationD:\Chrome\Google\Chrome\Ap…