Linux下C++实现目录的递归拷贝和删除

开发过程中需要对Linux的文件和目录进行拷贝和删除,各种查找发现C++居然没有相关功能的标准接口,于是就各方查找,希望能够找到某位大佬分享的成熟方案,but并没有找到我想要的。

于是便参考Linux公社的一个帖子关于目录拷贝的实现思路,并在其基础上增加了递归删除的功能,在此贴上代码作为笔记,以备下次使用。

#include <iostream>
#include <string.h>
#include <fstream>
#include <cstdio>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>



/* Check whether the path identified by 'filename' is a file */
static bool isFile(const std::string& filename) {
    struct stat   buffer;
    return (stat (filename.c_str(), &buffer) == 0 && S_ISREG(buffer.st_mode));
}

/* Check whether the path identified by 'filefodler' is a fodler */
static bool isDirectory(const std::string& filefodler) {
    struct stat   buffer;
    return (stat (filefodler.c_str(), &buffer) == 0 && S_ISDIR(buffer.st_mode));
}

/* Copy the file named by old_name to new_name */
int copyFile(const std::string& old_name, const std::string& new_name)
{
    std::ifstream ifs(old_name, std::ifstream::binary);
    std::ofstream ofs(new_name, std::ifstream::binary| std::ifstream::trunc);
    if(ifs.good() == false)
    {
        return -1;
    }

    ofs << ifs.rdbuf();

    ifs.close();
    ofs.close();
    return 0;
}

/* Copy all files and sub directories in directory to new path */
int copyFileAndDirectory(const std::string& old_path, const std::string& new_path)
{
    int result = 0;
    DIR * p_dir;  
    struct dirent * p_dirent; 

    if(isDirectory(old_path))
    {
        if(access(new_path.c_str(),0) == -1)
        {
            if(mkdir(new_path.c_str(), 0755) < 0)
            {
                std::cout<< "[copyFileAndDirectory] mkdir failed , the errno = " << strerror(errno) << std::endl;
                return -1;
            }
        }

        if((p_dir = opendir(old_path.c_str())) == NULL )
        {  
            std::cout << "Usage:cp -r <src_dir> <dat_dir> error: " << strerror(errno) << std::endl;
            return -1;  
        }  

        while((p_dirent = readdir(p_dir)) != NULL)
        {
            std::string file_name = old_path + "/" + p_dirent->d_name;
            std::string new_file_name = new_path + "/" + p_dirent->d_name;
            // It is a directory
            if(isDirectory(file_name) && (0 != strcmp(p_dirent->d_name, ".")) && (0 != strcmp(p_dirent->d_name, "..")))
            {
                result = copyFileAndDirectory(file_name,new_file_name);
                if(result < 0)
                {
                    return result;
                }
            }
            else if((0 != strcmp(p_dirent->d_name, ".")) && (0 != strcmp(p_dirent->d_name, "..")))
            {
                result = copyFile(file_name, new_file_name);
                if(result < 0)
                {
                    return result;
                }
            }
        }
        closedir(p_dir);
    }
    return result;
}

/* Remove all files and sub directories in directory */
int removeFileAndDirectory(const std::string& path)
{
    int result = 0;
    DIR * p_dir;
    struct dirent * p_dirent;
    if(isDirectory(path))
    {
        if((p_dir = opendir(path.c_str())) == NULL )  
        {  
            std::cout << "Opendir error: " << strerror(errno) << std::endl;
            return -1;  
        }  

        while((p_dirent = readdir(p_dir)) != NULL)
        {
            std::string file_name = path + "/" + p_dirent->d_name;
            /* It is a directory */
            if(isDirectory(file_name) && (0 != strcmp(p_dirent->d_name, ".")) && (0 != strcmp(p_dirent->d_name, "..")))
            {
                result = removeFileAndDirectory(file_name);
                if(result < 0)
                {
                    return result;
                }
            }
            /* It is a file */
            else if((0 != strcmp(p_dirent->d_name, ".")) && (0 != strcmp(p_dirent->d_name, "..")))
            {
                result = remove(file_name.c_str());
                if(result < 0)
                {
                    return result;
                }
            }
            else
            {
                /* do nothing */
            }
        }
        closedir(p_dir);
        result = rmdir(path.c_str());
    }
    else if(isFile(path))
    {
        result = remove(path.c_str());
    }
    else
    {
        /* do nothing */
    }
    return result;
}

int main(void)
{

    std::string src = "/Test/test";
    std::string des = "/Test/test2";
    int result = copyDirectory(src, des);
    std::cout<< result << std::endl;
    result = removeFileAndDirectory(des);
    std::cout<< result << std::endl;
    return 0;
}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Linux C++中,可以使用mkdir函数递归创建文件夹。mkdir函数原型如下: ```c++ int mkdir(const char *pathname, mode_t mode); ``` 其中,`pathname`参数指定需要创建的文件夹路径,`mode`参数指定创建文件夹的权限。 实现递归创建文件夹的方法是,在调用mkdir函数时,先判断需要创建的文件夹是否已经存在,如果不存在则递归调用mkdir函数创建上层目录。 下面是一个递归创建文件夹的示例代码: ```c++ #include <sys/stat.h> #include <sys/types.h> #include <unistd.h> #include <iostream> bool createDir(const std::string& path) { if(path.empty()) { return false; } int ret = mkdir(path.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); if(ret == 0) { std::cout << "Directory created: " << path << std::endl; return true; } else if(errno == EEXIST) { std::cout << "Directory already exists: " << path << std::endl; return true; } else { std::size_t pos = path.find_last_of('/'); if(pos == std::string::npos) { return false; } std::string parentPath = path.substr(0, pos); if(!createDir(parentPath)) { return false; } return mkdir(path.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) == 0; } } int main() { std::string path = "/tmp/test1/test2/test3"; createDir(path); return 0; } ``` 该代码将创建/tmp/test1/test2/test3目录,如果目录已经存在,则直接返回。如果目录不存在,则递归创建上层目录。注意,权限参数可以根据实际需求进行修改。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值