如何递归删除目录?

问题描述 投票:5回答:5

RemoveDirectory();仅删除空目录,但如何删除包含文件的目录?

c++ windows
5个回答
4
投票

如果您准备使用Windows API,那么完成此操作的最简单方法是调用SHFileOperation。使用FO_DELETE操作,不要忘记双重终止目录名。


7
投票

如果你可以使用它,最好的解决方案是boost::filesystem::remove_all。这样,您就不必担心平台特定的东西了。我不知道任何其他独立于平台的解决方案;通常的方式是否会涉及读取目录,并以递归方式降序(但是读取目录的方式也使用boost::filesystem或系统相关代码)。


3
投票

通常,如果没有可用的库方法,则通过递归完成。函数迭代所有目录条目,删除“普通”文件并使用找到的任何目录路径调用自身。这会破坏整个目录树,(我的Windows版本对传递的路径进行了明确的检查,以防止它在意外传入自杀参数的情况下销毁OS文件夹)。


3
投票

这可能很蹩脚,但考虑使用

system("rd /s /q ...");

这很丑陋,但忽略它太简单了。它还具有所有“如何处理网络共享上的文件”的东西。无论你想出什么解决方案,都可能是rd的(不完整和/或不正确)重新实现,因此调用外部进程实际上是很好的代码重用。 ;-)


2
投票

根据MSDN,当与相对路径一起使用时,SHFileOperation不是线程安全的。它只能安全​​地与绝对路径一起使用。

我建议使用此代码:

double directory_delete(char *pathname)
{
    string str(pathname);
    if (!str.empty())
    {
        while (*str.rbegin() == '\\' || *str.rbegin() == '/')
        {
            str.erase(str.size()-1);
        }
    }
    replace(str.begin(),str.end(),'/','\\');

    struct stat sb;
    if (stat((char *)str.c_str(),&sb) == 0 &&
        S_ISDIR(sb.st_mode))
    {
            HANDLE hFind;
            WIN32_FIND_DATA FindFileData;

            TCHAR DirPath[MAX_PATH];
            TCHAR FileName[MAX_PATH];

            _tcscpy(DirPath,(char *)str.c_str());
            _tcscat(DirPath,"\\*");
            _tcscpy(FileName,(char *)str.c_str());
            _tcscat(FileName,"\\");

            hFind = FindFirstFile(DirPath,&FindFileData);
            if (hFind == INVALID_HANDLE_VALUE) return 0;
            _tcscpy(DirPath,FileName);

            bool bSearch = true;
            while (bSearch)
            {
                if (FindNextFile(hFind,&FindFileData))
                {
                    if (!(_tcscmp(FindFileData.cFileName,".") &&
                        _tcscmp(FindFileData.cFileName,".."))) continue;
                    _tcscat(FileName,FindFileData.cFileName);
                    if ((FindFileData.dwFileAttributes &
                    FILE_ATTRIBUTE_DIRECTORY))
                    {
                        if (!directory_delete(FileName))
                        {
                            FindClose(hFind);
                            return 0;
                        }
                        RemoveDirectory(FileName);
                        _tcscpy(FileName,DirPath);
                    }
                    else
                    {
                        if (FindFileData.dwFileAttributes &
                            FILE_ATTRIBUTE_READONLY)
                            _chmod(FileName, _S_IWRITE);

                        if (!DeleteFile(FileName))
                        {
                            FindClose(hFind);
                            return 0;
                        }
                        _tcscpy(FileName,DirPath);
                    }
                }
                else
                {
                    if (GetLastError() == ERROR_NO_MORE_FILES)
                        bSearch = false;
                    else
                    {
                        FindClose(hFind);
                        return 0;
                    }
                }
            }
            FindClose(hFind);

            return (double)(RemoveDirectory((char *)str.c_str()) == true);
    }
    else
    {
        return 0;
    }
}

如果你想“按原样”使用我的代码,你需要在cpp文件的顶部使用这些标题:

#include <windows.h> // winapi
#include <sys/stat.h> // stat
#include <tchar.h> // _tcscpy,_tcscat,_tcscmp
#include <string> // string
#include <algorithm> // replace

using namespace std;

......我认为就是这样。

我的代码基于这篇文章:

http://www.codeguru.com/cpp/w-p/files/folderdirectorymaintenance/article.php/c8999/Deleting-a-Directory-Along-with-SubFolders.htm

我强烈建议永远不要使用SHFileOperation,除了安全问题之外,它自Windows Vista以来被IFileOperation取代。

希望这可以帮助!

© www.soinside.com 2019 - 2024. All rights reserved.