C++ Win32 刪除文件夾(非空)

#pragma once

#include <string>
#include <vector>
#include <algorithm>

// SHFileOperation
#include <Shlwapi.h>
#pragma comment (lib,"Shlwapi.lib")

// iFileType,0:文件夾,1:文件
//void PrintFold(int iCurrentLevel, int iFileType, std::string strPath, std::string strFileName)
//{
//	if (iFileType == 0)
//	{
//		printf(_T("文件夾:%d: %s\\%s\n"), iCurrentLevel, strPath.c_str(), strFileName.c_str());
//	}
//	else
//	{
//		printf(_T("文件:%d: %s\\%s\n"), iCurrentLevel, strPath.c_str(), strFileName.c_str());
//	}	
//}


// strPath的格式爲c:/ss/ww
// iCurrentLevel:當前文件層級,0開始
// uiEndLevel:遍歷層級深度,-1爲遍歷所有層級, 比如爲0時只遍歷當前目錄
template<class TTraverseProcess>
bool TraverseFold(std::wstring strPath, TTraverseProcess& TP, std::wstring strWildcard = _T("\\*.*"), unsigned int uiEndLevel = -1, unsigned int iCurrentLevel = 0)
{
	if (iCurrentLevel > uiEndLevel)
	{// 到達遍歷指定深度
		return true;
	}
	WIN32_FIND_DATA findFileData;

	std::wstring strFindPath = strPath + strWildcard;	//這裏一定要指明通配符,不然不會讀取所有文件和目錄

	HANDLE hFind = ::FindFirstFile(strFindPath.c_str(), &findFileData);
	if (INVALID_HANDLE_VALUE == hFind) {
		return false;
	}
	//遍歷文件夾
	do
	{
		std::wstring strFileName = findFileData.cFileName;
		if (strFileName != L"." && strFileName != L"..")
		{//不是當前路徑或者父目錄的快捷方式
		 //printf(_T("%d: %s\\%s\n"), iCurrentLevel, strPath.c_str(), strFileName.c_str());
			if (findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
			{//是一個普通目錄
			 //設置下一個將要掃描的文件夾路徑
				strFindPath = strPath + std::wstring(L"\\") + strFileName;
				//遍歷該目錄
				TraverseFold(strFindPath, TP, strWildcard, uiEndLevel, iCurrentLevel + 1);
				// 處理函數對象
				TP(iCurrentLevel, 0, strPath, strFileName);
			}
			else
			{//是一個文件
				TP(iCurrentLevel, 1, strPath, strFileName);
			}
		}
	} while (::FindNextFile(hFind, &findFileData));//尋找下一個目錄或者文件
	::FindClose(hFind);
	return true;
}

// 刪除文件夾
bool KDeleteDirectory(std::wstring strDelDir, std::wstring& strErr)
{
	class FindAllFiles
	{
	public:
		void operator()(int iCurrentLevel, int iFileType, std::wstring strPath, std::wstring strFileName)
		{
			if (iFileType == 0)
			{
				//wprintf_s(L"文件夾:%d: %s\\%s\n", iCurrentLevel, strPath.c_str(), strFileName.c_str());
				strFoldPathVec.push_back(std::pair<int, std::wstring>(iCurrentLevel, strPath + L"\\" + strFileName));
			}
			else
			{
				//wprintf_s(L"文件:%d: %s\\%s\n", iCurrentLevel, strPath.c_str(), strFileName.c_str());
				strFilePathVec.push_back(strPath + L"\\" + strFileName);
			}
		}
	public:
		std::vector<std::wstring> strFilePathVec;
		std::vector<std::pair<int, std::wstring>> strFoldPathVec;
	};
	//遍歷所有考試文件夾,獲取考試文件夾
	FindAllFiles allFiles;
	TraverseFold(strDelDir, allFiles, L"\\*.*");
	for (size_t i = 0; i < allFiles.strFilePathVec.size(); ++i)
	{
		if (!::DeleteFile(allFiles.strFilePathVec[i].c_str()))
		{
			strErr = std::wstring(L"刪除文件失敗,") + allFiles.strFilePathVec[i];
			return false;
		}
	}
	std::sort(allFiles.strFoldPathVec.begin(), allFiles.strFoldPathVec.end(), [](std::pair<int, std::wstring>& lt, std::pair<int, std::wstring>& rt) {
		return lt.first > rt.first;
	});
	for (size_t i = 0; i < allFiles.strFoldPathVec.size(); ++i)
	{
		if (!::RemoveDirectory(allFiles.strFoldPathVec[i].second.c_str()))
		{
			strErr = std::wstring(L"刪除文件夾失敗,") + allFiles.strFoldPathVec[i].second;
			return false;
		}
	}
	if (!::RemoveDirectory(strDelDir.c_str()))
	{
		strErr = std::wstring(L"刪除文件夾失敗,") + strDelDir;
		return false;
	}
	return true;
}

bool KDeleteDirectorySH(std::wstring strDelDir, std::wstring& strErr)
{
	SHFILEOPSTRUCTW FileOp;
	FileOp.fFlags = FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_SILENT;// | FOF_ALLOWUNDO/*刪除到回收站*/
	FileOp.hNameMappings = NULL;
	FileOp.hwnd = NULL;
	FileOp.lpszProgressTitle = NULL;
	strDelDir.push_back('\0');
	FileOp.pFrom = strDelDir.c_str();
	FileOp.pTo = NULL;
	FileOp.wFunc = FO_DELETE;
	int iReturn = SHFileOperationW(&FileOp);
	if (0 != iReturn)
	{
		strErr = std::wstring(L"刪除文件夾失敗,") + strDelDir;
		return false;
	}
	return true;
}

既然有SHFileOperation,爲什麼要自己遍歷文件夾呢,因爲在實際使用中發現SHFileOperation非常耗時,自己遍歷文件夾刪除完大概只要幾十毫秒,SHFileOperation則需要1秒多,很無語的,在刪除大量文件夾時就會覺得進度很慢

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章