以递归方式删除目录和文件的问题

时间:2013-06-11 20:49:23

标签: c++ recursion directory

我正在尝试从命令行解释器中删除所有文件和子目录。当调用rmdir -s newFolder时,我调用一个函数removeAll,它遍历所有文件和子文件夹并删除所有文件。

例如,如果我想删除文件newFolder,我删除所有文件并进入newFolder1。我删除newFolder1中的所有文件并进入newFolder2并删除所有文件。所以现在我在newFolder 2中,newFolder,newFolder1和newFolder2都是空的。

我的问题是如何递归备份并删除这3个空文件夹。我已调试并在此工作了几个小时,我只是没有得到它。谢谢

这是成功删除一个空文件夹的功能,否则会调用removeAll。

void MyShell::rmdir () {
//Error Check
if(argc != 3) {
    printf("USAGE: rmdir [-s] <directory>\n");      
    return;
}
else if(stricmp(cwd, argv[2]) == 0){
    printf("Cannot remove the current working directory");
    return;
}
if(_rmdir(argv[2]) == 0)
    return;

removeAll(argv[2]); 

}

函数removeAll成功删除所有子文件夹中的所有文件

void removeAll(char *path)
{
    _chdir(path);

    _finddata_t data;

    intptr_t handle = _findfirst("*", &data);

    if(handle == -1)
    {
        return;
    }

    do 
    {
        if (strcmp(data.name, ".") == 0 || strcmp(data.name, "..") == 0)
        {
            continue;
        }

        remove(data.name);

        if(data.attrib & _A_SUBDIR)
        {
            removeAll(data.name);
        }

    } while(_findnext(handle, &data) != -1);

    _findclose(handle); 
}

我想要重新加载并删除所有子文件夹的想法是在从findnext循环中断后调用一个方法

void removeDirectory(char *path)
{
    _finddata_t data;

    intptr_t handle = _findfirst("*", &data);

    if(handle == -1)
    {
        return;
    }

    do 
    {
        if (strcmp(data.name, ".") == 0 || strcmp(data.name, "..") == 0)
        {
            continue;
        }


        if(data.attrib & _A_SUBDIR)
        {
            if(_rmdir(data.name) == 0)
            {
                _chdir("..");
                removeDirectory(path);
            }

        }

    } while(_findnext(handle, &data) != -1);

    _findclose(handle); 
}

2 个答案:

答案 0 :(得分:1)

递归的全部意义在于你不必“备份”。递归例程的每次迭代都应该只处理它自己的级别,然后再次调用自身或者中断。看起来你几乎完成了它。尝试使用RemoveAll例程:

void removeAll(char *path)
{
    _chdir(path);

    _finddata_t data;

    intptr_t handle = _findfirst("*", &data);

    if(handle == -1)
    {
        return;
    }

    while(_findnext(handle, &data) != -1)   // changed from do..while to just while
    {
        if (strcmp(data.name, ".") == 0 || strcmp(data.name, "..") == 0)
        {
            continue;
        }

        if(data.attrib & _A_SUBDIR)
        {
            removeAll(data.name);
            _rmdir(data.name);    // <- moved this to here
        }
        else
        {
            remove(data.name);
        }
    }

    _findclose(handle); 
}

答案 1 :(得分:1)

假设remove()将删除空目录以及文件,您只需要将代码重新排列为:

do 
{
    if (strcmp(data.name, ".") == 0 || strcmp(data.name, "..") == 0)
    {
        continue;
    }

    if(data.attrib & _A_SUBDIR)
    {
        removeAll(data.name);
    }

    remove(data.name);

} while(_findnext(handle, &data) != -1);

基本上,你的递归函数应该遵循这个伪代码:

void deleteAll(path)
{
    for each file in path
    {
        if file is folder
        {
            // empty the folder
            deleteAll(file)
        }

        delete file // whether it is a now-empty folder or a file
    }
}

这样,当您遇到文件夹时,立即输入并删除其内容,然后返回其父文件夹的范围,您现在可以删除它,因为它是空的。