MFC中如何在指定目录下查找文件(模拟Windows文件搜索)

本文探讨了MFC的CFileFind类在文件搜索上的局限性,指出其与Windows内置搜索的区别,并提供了一个名为`WildcardSearch`的函数实现,该函数通过添加通配符来模拟Windows的广泛搜索。在代码示例中,详细说明了如何处理不同类型的文件名以实现更全面的搜索,并介绍了递归搜索子目录的功能。
摘要由CSDN通过智能技术生成

1 MFC中CFileFind搜索与Windows搜索功能的区别

使用MFC的CFileFind类进行文件搜索时,其结果和Windows自带的文件搜索程序差异较大。例如,在其方法CFileFind::FindFile()函数中,如果搜索的文件名为"C:\Users\cn.dwg",它只会搜索 “C:\Users\” 目录下所有”cn.dwg“的文件;但是Winodws自带的搜索却可以搜索到诸如”cn1.dwg“ "cn2.dwg"之类的结果。
经过自己初步试验,如果想要在MFC中尽可能模仿Windows搜索的做法,需要在搜索文件名中加入部分通配符(CFileFind支持通配符)

  1. 如果搜索的文件名包含扩展名,且文件名最后一位不是 * 或者 ? ,应在这个文件名最后加上*
  2. 如果搜索的文件名包含扩展名,且扩展名前面一位不是 * 或者 ? ,应在扩展名的前面加上 *
  3. 如果搜索的文件名不包含扩展名,应在这个文件名后面加上 *

2 代码实现

按照以上原则,文件搜索的实现代码为

//---------------------------------------------
//=Function Name:   WildcardSearch
//=Description:  	支持在特定目录下递归查找某个文件,文件名支持通配符
//=Parameter:       pszFileName 要查找的文件名
//=Parameter:       pszDir 要在哪个目录下查找
//=Parameter:       arFindResult 查找的结果保存在这个数组
//=Parameter:       int iRecursionCount 递归查找的深度,0代表在当前目录下查找;大于0代表递归深度;-1代表递归到最后一层。
//---------------------------------------------
void WildcardSearch(const TCHAR* pszFileName, const TCHAR* pszDir, std::vector<CString>& arFindResult, int iRecursionCount)
{
	if (!_tcsicmp(pszFileName, _T("")) || !_tcsicmp(pszDir, _T("")))
		return;

	CString sWildcarFullpath(pszDir);
	if (sWildcarFullpath.Right(1) != _T("\\"))
		sWildcarFullpath += _T("\\");

	CString sFileName(pszFileName);
	int iDotPos = -1;
	iDotPos = sFileName.ReverseFind(_T('.'));	//是否含文件扩展名
	if (0 <= iDotPos)
	{
		//扩展名前加上"*"
		if (iDotPos > 0)
		{
			if (_T('*') != sFileName[iDotPos - 1] && _T('?') != sFileName[iDotPos - 1])
				sFileName.Insert(iDotPos, _T('*'));
		}
		else
			sFileName.Insert(iDotPos, _T('*'));

		//如果扩展名最后一位不是*或者?,加上*
		if (_T('*') != sFileName[sFileName.GetLength() - 1] && _T('?') != sFileName[sFileName.GetLength() - 1])
			sFileName.Insert(sFileName.GetLength(), _T('*'));
	}
	else
		sFileName += _T('*');
	sWildcarFullpath += sFileName;

	//首先搜索当前文件夹下的所有文件
	CFileFind finder;
	BOOL bWorking = finder.FindFile(sWildcarFullpath);
	while (bWorking)
	{
		bWorking = finder.FindNextFile();
		if (!finder.IsDirectory() && !finder.IsDots() && !finder.IsHidden())
		{
			CString sFind;
			sFind = finder.GetFilePath();
			arFindResult.push_back(sFind);
		}
	}
	finder.Close();

	//递归搜索当前文件夹下的所有子目录
	sWildcarFullpath = pszDir;
	if (sWildcarFullpath.Right(1) != _T("\\"))
		sWildcarFullpath += _T("\\");
	sWildcarFullpath += _T("*.*");
	bWorking = finder.FindFile(sWildcarFullpath);
	while (bWorking)
	{
		bWorking = finder.FindNextFile();
		if(finder.IsDots())
			continue;
		else if (finder.IsDirectory())
		{
			if (-1 == iRecursionCount)
			{
				CString str = finder.GetFilePath();
				WildcardSearch(pszFileName, str, arFindResult, iRecursionCount);
			}
			else if (iRecursionCount > 0)
			{
				CString str = finder.GetFilePath();
				WildcardSearch(pszFileName, str, arFindResult, iRecursionCount - 1);
			}
		}
	}
	finder.Close();
}
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_Santiago

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值