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支持通配符)
- 如果搜索的文件名包含扩展名,且文件名最后一位不是 * 或者 ? ,应在这个文件名最后加上*
- 如果搜索的文件名包含扩展名,且扩展名前面一位不是 * 或者 ? ,应在扩展名的前面加上 *
- 如果搜索的文件名不包含扩展名,应在这个文件名后面加上 *
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();
}