直接貼代碼,我在本地測試過了。注意删除檔案時如果有隻讀檔案,也會遇到權限問題而導緻删除失敗,還有就是遞歸删除目錄在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);
}