RemoveDirectory();仅删除空目录,但如何删除包含文件的目录?
答案 0 :(得分:7)
如果可以使用,最佳解决方案是boost::filesystem::remove_all
。这样,您就不必担心平台特定的东西了。我不知道任何其他独立于平台的解决方案;通常的方法是读取目录,然后以递归方式降序(但是读取目录的方式也使用boost::filesystem
或系统相关代码。)
答案 1 :(得分:4)
如果您准备使用Windows API,那么完成此操作的最简单方法是致电SHFileOperation
。使用FO_DELETE
操作,不要忘记双重终止目录名。
答案 2 :(得分:3)
通常,如果没有可用的库方法,则通过递归完成。函数迭代所有目录条目,删除“普通”文件并使用找到的任何目录路径调用自身。这会破坏整个目录树,(我的Windows版本对传递的路径进行了明确的检查,以防止它在意外传入自杀参数时破坏OS文件夹。)
答案 3 :(得分:3)
这可能很蹩脚,但请考虑使用
system("rd /s /q ...");
这很难看,但忽略它太简单了。它还具有所有“如何处理网络共享上的文件”的东西。无论你想出什么解决方案,都可能是rd
的(不完整和/或不正确)重新实现,因此调用外部进程实际上是很好的代码重用。 ; - )
答案 4 :(得分: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;
......我认为就是这样。
我的代码基于这篇文章:
我强烈建议永远不要使用SHFileOperation,除安全问题外,自Windows Vista以来它已被IFileOperation取代。
希望这有帮助!