• 【转载】Linux C++ 实现文件目录常见操作(拷贝文件,拷贝目录,获取文件大小,获取目录大小,获取目录下所有文件名,...)


    原文:https://www.cnblogs.com/sinicheveen/p/13680327.html

    1. 环境

    • Linux(Ubuntu)
    • C++11
    • gcc 7.5.0
    • g++ 7.5.0
    • 这些常用操作封装为了一个 C++ 类 FileOperation
    • 对文件的操作基本都是使用的 C 函数,没有用 C++ 的 fstream 相关类
    • 针对 Linux 系统写的,涉及到 Linux 专有函数,因此对 Windows 系统可能不适用

    2. 代码

    FileOperation.h

    复制代码
    #pragma once
    
    /*
    *Environment:
    *Linux(Ubuntu), C++11,gcc 7.5.0,g++ 7.5.0
    *Description:
    *文件和目录操作(e.g. 拷贝文件,拷贝目录,计算目录大小,...)
    */
    
    #ifndef PARAMETER_FLOW
    #define PARAMETER_FLOW
    #define IN
    #define OUT
    #define INOUT
    #endif    //PARAMETER_FLOW
    
    #ifndef BASE_TYPE_DEF
    #define BASE_TYPE_DEF
    #include <stdint.h>
    typedef int16_t          SHORT;
    typedef uint16_t         USHORT;
    typedef int32_t          INT;
    typedef uint32_t         UINT;
    typedef int64_t          DLONG;
    typedef uint64_t         DULONG;
    typedef void             VOID;
    typedef bool             BOOL;
    typedef signed char      CHAR;
    typedef signed char      BYTE;
    typedef unsigned char    UCHAR;
    typedef float            FLOAT;
    typedef double           DOUBLE;
    #endif    //BASE_TYPE_DEF
    
    #include <dirent.h>
    #include <string>
    #include <string.h>
    #include <sys/stat.h>
    #include <type_traits>
    #include <unistd.h>
    #include <utility>
    #include <vector>
    #include <sys/vfs.h>
    
    using std::make_pair;
    using std::pair;
    using std::string;
    using std::vector;
    
    /*
    Explain:
     - fileLongName:加了路径的文件名,e.g. /root/xxx/1.txt
     - fileShortName:没有加路径的文件名,e.g. 1.txt
     - dirLongName:加了路径的目录名,e.g. /root/xxx/MyDocuments
     - dirShortName:没有加路径的目录名,e.g. MyDocuments
    */
    
    class FileOperation
    {
    public:
        /*
        *Function    : getDirSize
        *Description : 获取目录大小
        *Modify      : 2020.09.16
        *Input       : IN const string& dirLongName,目录名
        *            : OUT DLONG& dirSize,目录大小,单位:字节
        *Return      : pair<BOOL, string>,<函数是否执行成功,执行失败时的错误信息>
        *Caution     : 目录末尾不能有斜杠,e.g. 正确传参:/root/xxx,错误传参:/root/xxx/
        */
        static pair<BOOL, string> getDirSize(IN const string& dirLongName, OUT DLONG& dirSize);
    
        /*
        *Function    : getDirSizeAndMaxFileSize
        *Description : 获取目录大小和其中最大文件大小
        *Modify      : 2020.09.16
        *Input       : IN const string& dirLongName,目录名
        *            : OUT DLONG& dirSize,目录大小,单位:字节
        *            : OUT DLONG& maxFileSize,目录中最大文件大小,单位:字节
        *Return      : pair<BOOL, string>,<函数是否执行成功,执行失败时的错误信息>
        *Caution     : 目录末尾不能有斜杠,e.g. 正确传参:/root/xxx,错误传参:/root/xxx/
        */
        static pair<BOOL, string> getDirSizeAndMaxFileSize(IN const string& dirLongName, OUT DLONG& dirSize, OUT DLONG& maxFileSize);
    
        /*
        *Function    : getFileSize
        *Description : 获取文件大小
        *Modify      : 2020.09.16
        *Input       : IN const string& fileLongName,文件名
        *            : OUT DLONG& fileSize,文件大小
        *Return      : pair<BOOL, string>,<函数是否执行成功,执行失败时的错误信息>
        *Caution     :
        */
        static pair<BOOL, string> getFileSize(IN const string& fileLongName, OUT DLONG& fileSize);
    
        /*
        *Function    : getDiskSpace
        *Description : 获取磁盘总容量和剩余容量
        *Modify      : 2020.09.16
        *Input       : IN const string& diskPath,磁盘路径,e.g. /root
        *            : OUT DLONG& totalSpace,磁盘总容量,单位:字节
        *            : OUT DLONG& freeSpace,磁盘剩余容量,单位:字节
        *Return      : pair<BOOL, string>,<函数是否执行成功,执行失败时的错误信息>
        *Caution     :
        */
        static pair<BOOL, string> getDiskSpace(IN const string& diskPath, OUT DLONG& totalSpace, OUT DLONG& freeSpace);
    
        /*
        *Function    : getAllFileShortNamesInDir
        *Description : 获取目录下所有文件的短文件名
        *Modify      : 2020.09.16
        *Input       : IN const string& dirLongName,目录名
        *            : OUT vector<string>& allFileShortNames,目录下所有文件的短文件名
        *Return      : pair<BOOL, string>,<函数是否执行成功,执行失败时的错误信息>
        *Caution     : 目录末尾不能有斜杠,e.g. 正确传参:/root/xxx,错误传参:/root/xxx/
        *            :
        */
        static pair<BOOL, string> getAllFileShortNamesInDir(IN const string& dirLongName, OUT vector<string>& allFileShortNames);
    
        /*
        *Function    : getAllFileLongNamesInDir
        *Description : 获取目录下所有文件的长文件名
        *Modify      : 2020.09.16
        *Input       : IN const string& dirLongName,目录名
        *            : OUT vector<string>& allFileLongNames,目录下所有文件的长文件名
        *Return      : pair<BOOL, string>,<函数是否执行成功,执行失败时的错误信息>
        *Caution     : 目录末尾不能有斜杠,e.g. 正确传参:/root/xxx,错误传参:/root/xxx/
        *            :
        */
        static pair<BOOL, string> getAllFileLongNamesInDir(IN const string& dirLongName, OUT vector<string>& allFileLongNames);
    
        /*
        *Function    : moveFileOrDir
        *Description : 移动文件或文件夹
        *Modify      : 2020.09.16
        *Input       : IN const string& srcLongName,源文件(文件夹)名
        *            : IN const string& destLongName,目标文件(文件夹)名
        *Return      : pair<BOOL, string>,<函数是否执行成功,执行失败时的错误信息>
        *Caution     : 如果 srcLongName 和 destLongName 指定相同的路径,则进行重命名操作
        *            : 如果 srcLongName 和 destLongName 指定不同的路径,则文件(文件夹)将移动到新位置
        *            : 如果 destLongName 为现有文件,则覆盖现有文件
        *            : 如果 destLongName 为现有文件夹,则执行失败
        */
        static pair<BOOL, string> moveFileOrDir(IN const string& srcLongName, IN const string& destLongName);
    
        /*
        *Function    : removeFile
        *Description : 删除文件
        *Modify      : 2020.09.15
        *Input       : IN const string& fileLongName,文件名
        *Return      : pair<BOOL, string>,<函数是否执行成功,执行失败时的错误信息>
        *Caution     :
        */
        static pair<BOOL, string> removeFile(IN const string& fileLongName);
    
        /*
        *Function    : removeDir
        *Description : 删除目录
        *Modify      : 2020.09.16
        *Input       : IN const string& dirLongName,目录名
        *Return      : pair<BOOL, string>,<函数是否执行成功,执行失败时的错误信息>
        *Caution     : 目录末尾不能有斜杠,e.g. 正确传参:/root/xxx,错误传参:/root/xxx/
        */
        static pair<BOOL, string> removeDir(IN const string& dirLongName);
    
        /*
        *Function    : copyFile
        *Description : 复制文件
        *Modify      : 2020.09.16
        *Input       : IN const string& srcFileLongName,源文件名
        *            : IN const string& destLongFileName,目标文件名
        *Return      : pair<BOOL, string>,<函数是否执行成功,执行失败时的错误信息>
        *Caution     :
        */
        static pair<BOOL, string> copyFile(IN const string& srcFileLongName, IN const string& destLongFileName);
    
        /*
        *Function    : copyDir
        *Description : 复制目录
        *Modify      : 2020.09.15
        *Input       : IN const string& dirLongName,源目录名
        *            : IN string& destDirPath,目标目录名
        *Return      : pair<BOOL, string>,<函数是否执行成功,执行失败时的错误信息>
        *Caution     : 目录末尾不能有斜杠,e.g. 正确传参:/root/xxx,错误传参:/root/xxx/
        *            :
        */
        static pair<BOOL, string> copyDir(IN const string& srcDirPath, IN const string& destDirPath);
    
        /*
        *Function    : truncateFile
        *Description : 截断文件
        *Modify      : 2020.09.15
        *Input       : IN const string& fileLongName,文件名
        *            : IN const DLONG len,文件长度截断为长度 len
        *Return      : pair<BOOL, string>,<函数是否执行成功,执行失败时的错误信息>
        *Caution     : 如果文件先前大于此大小,则多余的数据会丢失
        *            : 如果文件先前较短,则将其扩展,扩展部分填充为空字节('')
        *            : 截断后 struct stat 的 st_size 变为 len
        */
        static pair<BOOL, string> truncateFile(IN const string& fileLongName, IN const DLONG len);
    
    };    //FileOperation()
    复制代码

     

    FileOperation.cpp

    复制代码
    #include "FileOperation.h"
    
    pair<BOOL, string> FileOperation::getDirSize(IN const string& dirLongName, OUT DLONG& dirSize)
    {
        DIR* pDir = opendir(dirLongName.c_str());
        if (NULL != pDir)
        {
            struct dirent* pDirent = NULL;
            struct stat fileStat;
            string fileLongNameTmp;
            while (NULL != (pDirent = readdir(pDir)))
            {
                if (0 == strcmp(pDirent->d_name, ".") || 0 == strcmp(pDirent->d_name, ".."))
                {
                    continue;
                }
                else if (DT_DIR != pDirent->d_type)
                {
                    fileLongNameTmp = dirLongName + "/" + pDirent->d_name;
                    if (0 == stat(fileLongNameTmp.c_str(), &fileStat))
                    {
                        dirSize += fileStat.st_size;
                    }
                    else
                    {
                        return make_pair(false, "file long name: " + fileLongNameTmp + ", error message: " + strerror(errno));
                    }
                }
                else
                {
                    pair<BOOL, string> exeStat = getDirSize(dirLongName + "/" + pDirent->d_name, dirSize);
                    if (false == exeStat.first)
                    {
                        return exeStat;
                    }
                }
            }
    
            return make_pair(true, "");
        }
        else
        {
            return make_pair(false, "dir long name: " + dirLongName + ", error message: " + strerror(errno));
        }
    }    //getDirSize()
    
    pair<BOOL, string> FileOperation::getDirSizeAndMaxFileSize(IN const string& dirLongName, OUT DLONG& dirSize, OUT DLONG& maxFileSize)
    {
        DIR* pDir = opendir(dirLongName.c_str());
        if (NULL != pDir)
        {
            struct dirent* pDirent = NULL;
            struct stat fileStat;
            string fileLongNameTmp;
            while (NULL != (pDirent = readdir(pDir)))
            {
                if (0 == strcmp(pDirent->d_name, ".") || 0 == strcmp(pDirent->d_name, ".."))
                {
                    continue;
                }
                else if (DT_DIR != pDirent->d_type)
                {
                    fileLongNameTmp = dirLongName + "/" + pDirent->d_name;
                    if (0 == stat(fileLongNameTmp.c_str(), &fileStat))
                    {
                        dirSize += fileStat.st_size;
                        if (fileStat.st_size > maxFileSize)
                        {
                            maxFileSize = fileStat.st_size;
                        }
                    }
                    else
                    {
                        return make_pair(false, "file long name: " + fileLongNameTmp + ", error message: " + strerror(errno));
                    }
                }
                else
                {
                    pair<BOOL, string> exeStat = getDirSizeAndMaxFileSize(dirLongName + "/" + pDirent->d_name, dirSize, maxFileSize);
                    if (false == exeStat.first)
                    {
                        return exeStat;
                    }
                }
            }
    
            return make_pair(true, "");
        }
        else
        {
            return make_pair(false, "dir long name: " + dirLongName + ", error message: " + strerror(errno));
        }
    }    //getDirSizeAndMaxFileSize()
    
    pair<BOOL, string> FileOperation::getFileSize(IN const string& fileLongName, OUT DLONG& fileSize)
    {
        fileSize = 0;
    
        struct stat fileStat;
        if (0 == stat(fileLongName.c_str(), &fileStat))
        {
            fileSize = fileStat.st_size;
            return make_pair(true, "");
        }
        else
        {
            return make_pair(false, "file long name: " + fileLongName + ", error message: " + strerror(errno));
        }
    }    //getFileSize()
    
    pair<BOOL, string> FileOperation::getDiskSpace(IN const string& diskPath, OUT DLONG& totalSpace, OUT DLONG& freeSpace)
    {
        totalSpace = 0;
        freeSpace = 0;
    
        struct statfs diskStatfs;
        if (statfs(diskPath.c_str(), &diskStatfs) >= 0)
        {
            totalSpace = (DLONG)diskStatfs.f_bsize * (DLONG)diskStatfs.f_blocks;
            freeSpace = (DLONG)diskStatfs.f_bsize * (DLONG)diskStatfs.f_bfree;
            return make_pair(true, "");
        }
        else
        {
            return make_pair(false, "disk path: " + diskPath + ", error message: " + strerror(errno));
        }
    }    //getDiskSpace()
    
    pair<BOOL, string> FileOperation::getAllFileShortNamesInDir(IN const string& dirLongName, OUT vector<string>& allFileShortNames)
    {
        DIR* pDir = opendir(dirLongName.c_str());
        if (NULL != pDir)
        {
            struct dirent* pDirent = NULL;
            struct stat fileStat;
            while (NULL != (pDirent = readdir(pDir)))
            {
                if (0 == strcmp(pDirent->d_name, ".") || 0 == strcmp(pDirent->d_name, ".."))
                {
                    continue;
                }
                else if (DT_DIR != pDirent->d_type)
                {
                    allFileShortNames.emplace_back(pDirent->d_name);
                }
                else
                {
                    pair<BOOL, string> exeStat = getAllFileShortNamesInDir(dirLongName + "/" + pDirent->d_name, allFileShortNames);
                    if (false == exeStat.first)
                    {
                        return exeStat;
                    }
                }
            }
    
            return make_pair(true, "");
        }
        else
        {
            return make_pair(false, "dir long name: " + dirLongName + ", error message: " + strerror(errno));
        }
    }    //getAllFileShortNamesInDir()
    
    pair<BOOL, string> FileOperation::getAllFileLongNamesInDir(IN const string& dirLongName, OUT vector<string>& allFileLongNames)
    {
        DIR* pDir = opendir(dirLongName.c_str());
        if (NULL != pDir)
        {
            struct dirent* pDirent = NULL;
            struct stat fileStat;
            while (NULL != (pDirent = readdir(pDir)))
            {
                if (0 == strcmp(pDirent->d_name, ".") || 0 == strcmp(pDirent->d_name, ".."))
                {
                    continue;
                }
                else if (DT_DIR != pDirent->d_type)
                {
                    allFileLongNames.emplace_back(dirLongName + "/" + pDirent->d_name);
                }
                else
                {
                    pair<BOOL, string> exeStat = getAllFileLongNamesInDir(dirLongName + "/" + pDirent->d_name, allFileLongNames);
                    if (false == exeStat.first)
                    {
                        return exeStat;
                    }
                }
            }
    
            return make_pair(true, "");
        }
        else
        {
            return make_pair(false, "dir long name: " + dirLongName + ", error message: " + strerror(errno));
        }
    }    //getAllFileLongNamesInDir()
    
    pair<BOOL, string> FileOperation::moveFileOrDir(IN const string& srcLongName, IN const string& destLongName)
    {
        if (0 == rename(srcLongName.c_str(), destLongName.c_str()))
        {
            return make_pair(true, "");
        }
        else
        {
            return make_pair(false, "src file long name: " + srcLongName +
                ", dest file long name: " + destLongName + ", error message: " + strerror(errno));
        }
    }    //moveFileOrDir()
    
    pair<BOOL, string> FileOperation::removeFile(IN const string& fileLongName)
    {
        if (0 == remove(fileLongName.c_str()))
        {
            return make_pair(true, "");
        }
        else
        {
            return make_pair(false, "file long name: " + fileLongName + ", error message: " + strerror(errno));
        }
    }    //removeFile()
    
    pair<BOOL, string> FileOperation::removeDir(IN const string& dirLongName)
    {
        DIR* pDir = opendir(dirLongName.c_str());
        if (NULL != pDir)
        {
            struct dirent* pDirent = NULL;
            struct stat fileStat;
            while (NULL != (pDirent = readdir(pDir)))
            {
                if (0 == strcmp(pDirent->d_name, ".") || 0 == strcmp(pDirent->d_name, ".."))
                {
                    continue;
                }
                else if (DT_DIR != pDirent->d_type)
                {
                    pair<BOOL, string> exeStat = removeFile(dirLongName + "/" + pDirent->d_name);
                    if (false == exeStat.first)
                    {
                        return exeStat;
                    }
                }
                else
                {
                    pair<BOOL, string> exeStat = removeDir(dirLongName + "/" + pDirent->d_name);
                    if (false == exeStat.first)
                    {
                        return exeStat;
                    }
                }
            }
    
            return make_pair(true, "");
        }
        else
        {
            return make_pair(false, "dir long name: " + dirLongName + ", error message: " + strerror(errno));
        }
    }    //removeDir()
    
    pair<BOOL, string> FileOperation::copyFile(IN const string& srcFileLongName, IN const string& destLongFileName)
    {
        INT len = 0;
        FILE* pSrcFile = NULL;
        FILE* pDestFile = NULL;
        UINT bufferSize = 1 * 1024 * 1024;    //设置的过大也不会对性能有什么显著提升
        vector<CHAR> buffer(bufferSize, 0);
    
        if (NULL == (pSrcFile = fopen(srcFileLongName.c_str(), "rb")))
        {
            return make_pair(false, "source file long name: " + srcFileLongName + ", error message: " + strerror(errno));
    
        }
        if (NULL == (pDestFile = fopen(destLongFileName.c_str(), "wb")))
        {
            return make_pair(false, "dest file long name: " + destLongFileName + ", error message: " + strerror(errno));
        }
    
        while ((len = fread(&buffer[0], sizeof(BYTE), bufferSize, pSrcFile)) > 0)
        {
            fwrite(&buffer[0], sizeof(CHAR), len, pDestFile);
        }
        fclose(pDestFile);
        fclose(pSrcFile);
    
        return make_pair(true, "");
    }    //copyFile()
    
    pair<BOOL, string> FileOperation::copyDir(IN const string& srcDirPath, IN const string& destDirPath)
    {
        if (0 != mkdir(destDirPath.c_str(), 00777))
        {
            return make_pair(false, "dest dir path: " + destDirPath + ", error message: " + strerror(errno));
        }
    
        DIR* pDir = opendir(srcDirPath.c_str());
        if (NULL != pDir)
        {
            struct dirent* pDirent = NULL;
            while (NULL != (pDirent = readdir(pDir)))
            {
                if (0 == strcmp(pDirent->d_name, ".") || 0 == strcmp(pDirent->d_name, ".."))
                {
                    continue;
                }
                else if (DT_DIR != pDirent->d_type)
                {
                    pair<BOOL, string> exeStat = copyFile(srcDirPath + "/" + pDirent->d_name, destDirPath + "/" + pDirent->d_name);
                    if (false == exeStat.first)
                    {
                        return exeStat;
                    }
                }
                else
                {
                    pair<BOOL, string> exeStat = copyDir(srcDirPath + "/" + pDirent->d_name, destDirPath + "/" + pDirent->d_name);
                    if (false == exeStat.first)
                    {
                        return exeStat;
                    }
                }
            }
    
            return make_pair(true, "");
        }
        else
        {
            return make_pair(false, "source dir path: " + srcDirPath + ", error message: " + strerror(errno));
        }
    }    //copyDir()
    
    pair<BOOL, string> FileOperation::truncateFile(IN const string& fileLongName, IN const DLONG len)
    {
        if (0 == truncate(fileLongName.c_str(), len))
        {
            return make_pair(true, "");
        }
        else
        {
            return make_pair(false, "file long name: " + fileLongName + ", error message: " + strerror(errno));
        }
    }    //truncateFile()
    复制代码
  • 相关阅读:
    IS上部署MVC网站,打开后ExtensionlessUrlHandler-
    深拷贝与浅拷贝
    python小技巧---打印出不同颜色的输出
    环境搭建之allure的安装配置,及简单使用
    Python进行JSON格式化输出,以及汉字显示问题
    无限遍历,Python实现在多维嵌套字典、列表、元组的JSON中获取数据
    环境准备—之—linux下安装svn--开机自启--及format权限问题
    环境准备—之—linux下安装python3和pip3
    环境准备—之—linux下安装jdk
    问题1——之Linux虚拟机ip地址消失
  • 原文地址:https://www.cnblogs.com/cy1993/p/13680372.html
Copyright © 2020-2023  润新知