MFC对目录的递归创建、删除、拷贝和移动

直接贴代码,我在本地测试过了。注意删除文件时如果有只读文件,也会遇到权限问题而导致删除失败,还有就是递归删除目录在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);
}
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值