栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

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

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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

目录
  • 最“高效”的实现
  • 为什么会重复造轮子
  • 非递归方式的实现

最“高效”的实现

Linux下C++可以通过调用系统的system函数来执行shell命令,这无疑是最快的实现方法,话不多说,上代码。

#include 
#include 

void CopyFileAndDirectory(const std::string &_old_path, const std::string &_new_path)
{
    std::string copy_command = "cp -r " + _old_path + " " + _new_path;
    system(copy_command.c_str());
}

void RemoveFileAndDirectory(const std::string &_path)
{
    std::string remove_command = "rm -rf " + _path;
    system(remove_command.c_str());
}

没错,使用shell命令就是这么简单明了。

为什么会重复造轮子

在此之前我并不是很了解C++调用shell的操作,于是使用递归方式实现了一个版本(参见:Linux下C++实现目录的递归拷贝和删除),但是静态检查时MISRA规则要求不能使用递归。于是乎,我又开始思考怎么实现一个非递归的版本。

非递归方式的实现

实现细节在代码中详细注释了,偷了一下懒把两个主要接口的返回值类型都写成void了。

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 


static bool IsFile(const std::string &filename)
{
    struct stat buffer;
    return (stat(filename.c_str(), &buffer) == 0 && S_ISREG(buffer.st_mode));
}


static bool IsDirectory(const std::string &filefodler)
{
    struct stat buffer;
    return (stat(filefodler.c_str(), &buffer) == 0 && S_ISDIR(buffer.st_mode));
}


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;
}


void CopyFileAndDirectory(const std::string &_old_path, const std::string &_new_path)
{
    DIR *directory_ptr;
    struct dirent *dirent_ptr;

    
    std::queue< std::pair> path_queue;
    path_queue.push(std::pair(_old_path, _new_path));

    while (path_queue.size() > 0)
    {
        
        auto path_pair = path_queue.front();
        path_queue.pop();

        
        if (IsDirectory(path_pair.first))
        {
            
            if (access(path_pair.second.c_str(), 0) == -1)
            {
                
                if (mkdir(path_pair.second.c_str(), 0755) < 0)
                {
                    std::cout << "[CopyFileAndDirectory] mkdir failed , the errno = " << strerror(errno) << std::endl;
                }
            }

            
            if ((directory_ptr = opendir(path_pair.first.c_str())) == NULL)
            {
                std::cout << "open directory failed directory name = " << path_pair.first << std::endl;
            }

            
            while ((dirent_ptr = readdir(directory_ptr)) != NULL)
            {
                if((strcmp(dirent_ptr->d_name, ".") != 0) && (strcmp(dirent_ptr->d_name, "..") != 0))
                {
                    
                    auto old_file = path_pair.first + "/" + dirent_ptr->d_name;
                    auto new_file = path_pair.second + "/" + dirent_ptr->d_name;
                    path_queue.push(std::pair(old_file, new_file));
                }
            }
            closedir(directory_ptr);
        }
        else if (IsFile(path_pair.first))
        {
            
            CopyFile(path_pair.first, path_pair.second);
        }
        else
        {
            
        }
    }
}



void RemoveFileAndDirectory(const std::string &_path)
{
    DIR *directory_ptr;
    struct dirent *dirent_ptr;

    
    std::queue path_queue;
    std::vector path_set;
    path_queue.push(_path);

    
    while(path_queue.size() > 0)
    {
        
        auto path_name = path_queue.front();
        path_queue.pop();

        
        if(IsDirectory(path_name))
        {
            
            path_set.push_back(path_name);

            
            if ((directory_ptr = opendir(path_name.c_str())) == NULL)
            {
                std::cout << "Opendir error: " << strerror(errno) << std::endl;
            }

            
            while ((dirent_ptr = readdir(directory_ptr)) != NULL)
            {
                if((strcmp(dirent_ptr->d_name, ".") != 0) && (strcmp(dirent_ptr->d_name, "..") != 0))
                {
                    
                    auto item_path = path_name + "/" + dirent_ptr->d_name;
                    path_queue.push(item_path);
                }
            }

            closedir(directory_ptr);
        }
        else if(IsFile(path_name))
        {
            
            remove(path_name.c_str());
        }
        else
        {
            
        }
    }

    
    while(path_set.size() > 0)
    {
        auto last_item = path_set.back();
        path_set.pop_back();
        auto result = rmdir(last_item.c_str());
        if(result != 0)
        {
            std::cout<< "remove last_item failed = " << last_item << std::endl;
        }
    }
}

int main(void)
{
    std::string old_path = "/WorkSpace/TestPath";
    std::string new_path = "/WorkSpace/NewPath";
    CopyFileAndDirectory(old_path, new_path);
    RemoveFileAndDirectory(new_path);

    return 0;
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/929302.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号