windows 如何递归删除目录?

xkftehaa  于 2022-11-18  发布在  Windows
关注(0)|答案(5)|浏览(247)

RemoveDirectory()只删除空目录。如何删除包含文件的目录?

ijnw1ujt

ijnw1ujt1#

最好的解决方案是boost::filesystem::remove_all,如果你能使用它的话。这样,你就不必担心平台特定的东西。否则,通常的方式将涉及阅读目录并递归地将其降序(但是读取目录的方式还使用boost::filesystem或系统相关代码)。

lymnna71

lymnna712#

如果您准备使用Windows API,那么最简单的方法就是调用SHFileOperation。使用FO_DELETE操作,并且不要忘记以两个空值终止您的目录名。

gopyfrb3

gopyfrb33#

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

42fyovps

42fyovps4#

根据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所取代。

tzxcd3kk

tzxcd3kk5#

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

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

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

相关问题