直接贴代码,我在本地测试过了。注意删除文件时如果有只读文件,也会遇到权限问题而导致删除失败,还有就是递归删除目录在360等杀毒软件下会弹窗提示安全问题,毕竟是在大批量删除文件,尤其是文件夹带有游戏字样时。
关于反斜杠和顺斜杠,在windows里,顺斜杠只是为了兼容,但我在windows7里使用顺斜杠移动目录,当目标目录已经存在时,发现操作系统弹窗提示目标目录不存在,是否创建,我点是或点否,都无法成功移动目录。所以建议严格用反斜杠好了,在字符串里,反斜杠要用转义符,转义符也是反斜杠,所以出现总是两个反斜杠的写法。
下面所有函数都来自网上搜索,自己重构、测试后发布的,如果觉得侵犯版权,请留言,我先贴出一些参考过的地址:
MFC 递归删除文件夹下所有文件或文件夹
递归创建多级目录
MFC拷贝文件夹
MFC移动文件夹
/**
* 创建目录(支持同时创建多级目录)
* 传入参数:
* 1 反斜杠:如D:\\1\\2\\或D:\\1\\2
* 2 顺斜杠:如D:/1/2/或D:/1/2
* 参数最后的那个反斜杠可以有,也可以没有。
* 返回值:成功或目录本来已经存在时返回TRUE,否则返回FALSE
* 注意:如果权限不足或目录所在路径本来是一个文件,就会失败。
*/
BOOL CreateFolder(const CString &folderPath)
{
if (PathIsDirectory(folderPath))
{
return TRUE;
}
CString path = folderPath;
TCHAR dirName[256] = {0};
TCHAR *pFolderPath = path.GetBuffer(0);
TCHAR *pDirName = dirName;
while (*pFolderPath)
{
if (('\\' == *pFolderPath) || ('/' == *pFolderPath))
{
if (':' != *(pFolderPath - 1))
{
if (!PathIsDirectory(dirName) && !CreateDirectory(dirName, NULL))
{
return FALSE;
}
}
if ('\0' == *(pFolderPath + 1))
{
return TRUE;
}
}
*pDirName++ = *pFolderPath++;
*pDirName = '\0';
}
return CreateDirectory(folderPath, NULL);
}
/**
* 删除目录(包括目录中的所有目录和文件)
* 传入参数:
* 1 反斜杠:如D:\\1\\2\\或D:\\1\\2
* 2 顺斜杠:如D:/1/2/或D:/1/2
* 参数最后的那个反斜杠可以有,也可以没有。
* 返回值:成功或目录本来就不存在时返回TRUE,否则返回FALSE
* 注意:如果权限不足或目录所在路径本来是一个文件,就会失败。
*/
BOOL DeleteFolder(const CString &folderPath)
{
if (!PathIsDirectory(folderPath))
{
TRACE("OK\n");
return TRUE;
}
CFileFind filefind;
CString path = folderPath;
if (path.Right(1) != "\\" && path.Right(1) != "/")
path += "\\";
path += "*.*";
BOOL res = filefind.FindFile(path);
while (res)
{
res = filefind.FindNextFile();
if (!filefind.IsDots() && !filefind.IsDirectory())
{
CString filePath = filefind.GetFilePath();
if (!DeleteFile(filePath))
{
return FALSE;
}
}
else if (filefind.IsDots())
{
continue;
}
else if (filefind.IsDirectory())
{
CString pathDir = filefind.GetFilePath();
if (!DeleteFolder(pathDir))
{
return FALSE;
}
}
}
return RemoveDirectory((LPCTSTR)folderPath);
}
/**
* 递归拷贝目录
* 传入参数:
* 1 反斜杠:如D:\\1\\2\\或D:\\1\\2
* 2 顺斜杠:如D:/1/2/或D:/1/2
* 参数最后的那个反斜杠可以有,也可以没有。
* 返回值:成功返回TRUE,否则返回FALSE,如果目录本来就存在可能会失败!
*/
BOOL CopyFolder(CString strSrcPath, CString strTargetPath)
{
if (!::PathFileExists(strTargetPath))
{
if (!CreateFolder(strTargetPath))
{
return FALSE;
}
}
CFileFind finder;
BOOL bWorking = finder.FindFile(strSrcPath);
while (bWorking)
{
bWorking = finder.FindNextFile();
if (finder.IsDots())
{
continue;
}
else if (finder.IsDirectory())
{
if (!CopyFolder(finder.GetFilePath() + _T("\\*.*"), strTargetPath + _T("\\") + finder.GetFileName()))
{
return FALSE;
}
}
else
{
if (!CopyFile(finder.GetFilePath(), strTargetPath + _T("\\") + finder.GetFileName(), FALSE))
{
return FALSE;
}
}
}
return TRUE;
}
/**
* 递归移动目录,注意并不是拷贝后删除,那样效率太低了!
* 传入参数:
* 1 只允许反斜杠:如D:\\1\\2\\或D:\\1\\2
* 参数最后的那个反斜杠可以有,也可以没有。
* 返回值:成功返回TRUE,否则返回FALSE
* 注意:顺斜杠可能有一些问题。
* 如果目标目录本来就存在,第一次会导致移动到该目录下,第二次覆盖,比如D:/test到 D:/1/test,当D:/1/test目录已经存在时
*/
BOOL MoveFolder(const char *strSrcPath, const char *strTargetPath)
{
int srcLen = strlen(strSrcPath);
int targetLen = strlen(strTargetPath);
if (srcLen > 510 || targetLen > 510)
{
return FALSE;
}
char srcPath[512];
char targetPath[512];
strcpy(srcPath, strSrcPath);
strcpy(targetPath, strTargetPath);
srcPath[srcLen + 1] = 0; // 后2个字节都必须为0
targetPath[targetLen + 1] = 0; // 后2个字节都必须为0
SHFILEOPSTRUCT FileOp;
ZeroMemory((void *)&FileOp, sizeof(SHFILEOPSTRUCT));
FileOp.fFlags = FOF_NOCONFIRMATION;
FileOp.hNameMappings = NULL;
FileOp.hwnd = NULL;
FileOp.lpszProgressTitle = NULL;
FileOp.pFrom = strSrcPath; // 源地址
FileOp.pTo = strTargetPath; // 目的地址
FileOp.wFunc = FO_MOVE;
return 0 == SHFileOperation(&FileOp);
}