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

news2024/11/24 15:57:18

文章目录

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

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

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

相关文章

【机器学习-02】矩阵基础运算---numpy操作

在机器学习-01中&#xff0c;我们介绍了关于机器学习的一般建模流程&#xff0c;并且在基本没有数学公式和代码的情况下&#xff0c;简单介绍了关于线性回归的一般实现形式。不过这只是在初学阶段、为了不增加基础概念理解难度所采取的方法&#xff0c;但所有的技术最终都是为了…

FFmpeg转码参数说明及视频转码示例

-b : 设置音频或者视频的转码码率 -b:v 只设置视频码率 -b:a 只设置音频码率 -ab: 只设置音频码率, 默认码率大小为: 128k bit/s -g: 设置视频GOP大小,表示I帧之间的间隔,默认为12 -ar: 设置音频采样率,默认0 -ac: 设置音频通道数量 默认0 -bf: 设置连…

服务器机器学习环境搭建(包括AanConda的安装和Pytorch的安装)

服务器机器学习环境搭建 1 服务器与用户 在学校中&#xff0c;我们在学校中是以用户的身份进行访问学校的服务器的。整体框架大致如下&#xff1a; 我们与root用户共享服务器的一些资源&#xff0c;比如显卡驱动&#xff0c;Cuda以及一些其他的公共软件。 一般情况下&#…

Vue2在一个页面内动态切换菜单显示对应的路由组件

项目的需求是在一个页面内动态获取导航菜单&#xff0c;导航菜单切换的时候显示对应的路由页面&#xff0c;类似于tab切换的形式&#xff0c;切换的导航菜单和页面左侧导航菜单是同一个路由组件&#xff0c;只是放到了一个页面上&#xff0c;显示的个数不同&#xff0c;所有是动…

Docker----Dockerfile构建微服务镜像

目录 一、关键步骤 二、具体步骤 1、准备后端jar包(这里以java后端演示) 2、编写Dockerfile 3、构建镜像 4、运行镜像容器 5、测试是否成功 一、关键步骤 1、准备后端jar包(这里以java后端演示) 2、编写Dockerfile 3、构建镜像 4、运行镜像容器 5、测试是否成功 二…

C#,图论与图算法,图(Graph)的数据结构设计与源代码

因为后面即将发布的大量有关“图”的算法与源代码都需要用到下面的这些基础数据&#xff0c;为避免大家去下载&#xff0c;特意先发布于此。 一、图&#xff08;Graph&#xff09;的基础知识 图&#xff08;Graph&#xff09;是一组对象的图示&#xff0c;其中一些对象对通过链…

STM32(TIM定时器中断)

理论知识 定时器定时中断 接线图 定时器工作配置步骤 定时中断和内外时钟源选择 定时器中需要使用的函数 程序实现效果&#xff1a; void TIM_DeInit(TIM_TypeDef* TIMx); **// 恢复定时器的缺省配置**void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef*TIM…

jupyter中pip安装包会安装到别的环境。

文章目录 1. 查看jupyter当前环境和默认环境的路径和python版本2.安装包到正确的环境 如果你在 Jupyter Notebook 中使用 pip 安装包&#xff0c;它默认会将包安装到 Jupyter Notebook 所在的Python 环境。这可能会导致安装的包与你期望的环境不匹配。 1. 查看jupyter当前环境和…

RK3568平台开发系列讲解(基础篇)内核是如何发送事件到用户空间

🚀返回专栏总目录 文章目录 一、相关接口函数二、udevadm 命令三、实验沉淀、分享、成长,让自己和他人都能有所收获!😄 一、相关接口函数 kobject_uevent 是 Linux 内核中的一个函数, 用于生成和发送 uevent 事件。 它是 udev 和其他设备管理工具与内核通信的一种方式。…

mybatis源码阅读系列(二)

前言 上一篇文章mybatis源码阅读系列&#xff08;一&#xff09;介绍了mybatis和原生jdbc的区别&#xff0c;并通过代码展示了两者的运行过程和结果&#xff0c;下面让我们继续详细了解下mybatis的执行过程&#xff1b; package com.wyl.mybatis.service;import com.wyl.mybat…

给定参数c和长度为n的递增数组a(ai <= c), 对于0<=x<=y<=c, 求(x,y)的对数,满足x+y不是数组a中的元素且y-x不是a中元素

题目 思路&#xff1a; #include <bits/stdc.h> using namespace std; #define int long long #define pb push_back #define fi first #define se second #define lson p << 1 #define rson p << 1 | 1 const int maxn 1e6 5, inf 1e18, maxm 4e4 5, …

微信小程序关闭首页广告

由于之前微信小程序默认开启了首页广告位。导致很多老人误入广告页的内容&#xff0c;所以想着怎么屏蔽广告。好家伙&#xff0c;搜索一圈&#xff0c;要么是用户版本的屏蔽广告&#xff0c;或者是以下一个模棱两可的答案&#xff0c;要开发者设置一下什么参数的&#xff0c;如…

Opencascade基础教程(11):设置显示模式

1、设置显示模式 1.1 增加按钮添加消息响应函数 //线框 void COCCDemoDoc::OnButtonWireframemode() {//关闭边界框const Handle(Prs3d_Drawer)& aDrawer m_AISContext->DefaultDrawer();aDrawer->SetFaceBoundaryDraw(false);//线框m_AISContext->SetDisplayMo…

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

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

springboot蛋糕订购小程序的设计与实现

摘 要 相比于以前的传统手工管理方式&#xff0c;智能化的管理方式可以大幅降低商家的运营人员成本&#xff0c;实现了蛋糕订购的标准化、制度化、程序化的管理&#xff0c;有效地防止了蛋糕订购的随意管理&#xff0c;提高了信息的处理速度和精确度&#xff0c;能够及时、准确…

如何重置iPhone的网络设置?这里提供详细步骤

前言 本文介绍如何重置iPhone上的网络设置。该信息适用于iPhone 12到iPhone 6以及iOS 14到iOS 8。 如何在iPhone上重置网络设置 采取以下步骤重置iPhone上的网络设置&#xff1a; 1、在iPhone上&#xff0c;打开设置应用程序。 2、单击通用。 3、滚动到屏幕底部&#xff…

如何保存缓存和MySQL的双写一致呢?

如何保存缓存和MySQL的双写一致呢&#xff1f; 所谓的双写一致指的是&#xff0c;在同时使用缓存(如Redis)和数据库(如MySQL)的场景下,确保数据在缓存和数据库中的更新操作保持一致。当对数据进行修改的时候&#xff0c;无论是先修改缓存还是先修改数据库&#xff0c;最终都要保…

深度学习-解读GoogleNet深度学习网络

深度学习-解读GoogleNet深度学习网络 深度学习中&#xff0c;经典网络引领一波又一波的技术革命&#xff0c;从LetNet到当前最火的GPT所用的Transformer&#xff0c;它们把AI技术不断推向高潮。2012年AlexNet大放异彩&#xff0c;它把深度学习技术引领第一个高峰&#xff0c;打…

双向SSM: Vision Mamba Encoder

文章目录 Vision Mamba Encoder初始化输入映射序列变换参数映射BC参数映射delta参数映射 SSM参数初始化A , D矩阵初始化delta参数初始化 双向SSM初始化参数初始化 前向输入映射fast_pathuse_fast_pathno use_fast_path 双向SSMv1前向后向 v2前向后向 Vision Mamba Encoder Vis…

(四)Android布局类型(线性布局LinearLayout)

线性布局&#xff08;LinearLayout&#xff09;&#xff1a;按照一定的方向排列组件&#xff0c;方向主要分为水平方向和垂直方向。方向的设置通过属性android:orientation设置 android:orientation 其取值有两种 水平方向&#xff1a;android:orientation"horizontal&…