在《垃圾文件清理源代码详解2》最后我放进了ResearchFile函数下面,我们解释下。
strcat_s(szTmp, "\\*.*");
在文件名之后添加"//*.*"声明为通配文件,使得能够遍历所有的文件和目录。
接着就是定义文件查找结构体WIN32_FIND_DATA。然后我们利用FindFirstFile,FindNextFile遍历盘符中的文件,FindFirstFile()函数
函数功能描述:查找指定目录的第一个文件或目录并返回它的句柄
函数原型 :
HANDLE FindFirstFile(
LPCTSTR lpFileName, // 目录名
LPWIN32_FIND_DATA lpFindFileData // 数据缓冲区
);
参数:lpFileName
[输入] 指向字符串的指针用于指定一个有效的目录。
lpFindFileData
[输出] 指向一个WIN32_FIND_DATA的指针,用于存放找到文件或目录的信息。
BOOLFindNextFile(
HANDLE hFindFile, //searchhandle
LPWIN32_FIND_DATA lpFindFileData //databuffer
);
此函数用于遍历目录或文件时,判断当前目录下是否有下一个目录或文件参数 类型及说明
hFindFile Long,上一次查找返回的文件句柄
lpFindFileData WIN32_FIND_DATA,这个结构用于装载与找到的文件有关的信息。该结构可用于后续的搜索
findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY《WIN32_FIND_DATA结构体及文件查找程序小解》我已经解释过了,不懂的话,你可以看看。
if ((strcmp(findData.cFileName, "...") != 0) &&
(strcmp(findData.cFileName, "..") != 0) &&
(strcmp(findData.cFileName, ".") != 0))
在一个目录下面只操作目录下所有的文件和文件夹名称,忽略掉表示当前目录的. ,上一级目录的.. ,三个点是上两级目录。过流掉当前目录和当前所在文件夹(上一级目录)
当你读一个目录结构时,
会有两个特殊的名字: . 当前目录;
.. 上一级目录;
代码是把这两个过滤掉了
或许你觉得findData.cFileName不可能存储'.'或'..'我们断点调试就知道了。
在你需要断点调试的地方,右键选择断点-》插入断点就行了
跳出对话框,如上图。
如图,会直接跳到断点的地方。现在我们需要查看变量的值,有两种方法:
1:
接着就会跳出局部变量窗口:
二:当你直接把鼠标放在代码上编译器会自己,跳出很多信息,这时候你就可以查看了。这个更方便。
这里我们看到没有cfilename这个值的信息。那么我们就用第二张方法。直接将鼠标放到这句代码上,然后点击就能看到这些信息:
下面我们接着运行:
我们测试出来了,有‘..'这个值。
findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY利用if语句判断,只有当我们查找的文件最后是以文件路径的形式显示出来的,才能最后进入到if语句中,而不是else语句。那么此时就需要判断该文件的后缀是不是我们所选中的文件后缀了,因此,我们需要一个函数来判断那就是IsTmpFile(),实现代码:
BOOL CClearTmpFileDlg::IsTmpFile(char *pszFileName)
{
for (POSITION pos = m_FilterList.GetHeadPosition(); pos != NULL;)
{
//获取临时文件
char *szFilter = m_FilterList.GetNext(pos);
int nChar = '.';
char* pszDes = strrchr(szFilter, nChar); //过滤掉“.”之前的“*”符号
pszDes += 1; //过滤掉.,使得pszDes指向扩展名
//获取参数pszFileName的扩展名
char* pszExt = strrchr(pszFileName, nChar); //过滤掉“.”之前的“*”符号
if (pszExt == NULL) //如果pszFileName没有扩展名
{
pszExt = pszFileName;
}
else
{
pszExt += 1; //过滤掉.,使得pszExt指向扩展名
}
//根据扩展名判断pszFileName是否是临时文件
if (_stricmp(pszExt, pszDes) == 0) //扩展名相等
{
return TRUE;
}
}
return FALSE;
}
在这里,我就只讲for (POSITION pos = m_FilterList.GetHeadPosition(); pos != NULL;)这句代码。我在《清理垃圾文件软件源代码解析2》就说了至于m_FilterList.AddTail(szText);我稍后会做解释,你现在不需要管。但是现在就要管了。一开始写代码我们需要在对话框类的头文件中声明定义一个变量:CList<char*, char*> m_FilterList; //记录需要查找的临时文件扩展名
而在GetTmpExtName函数中我就把所有的需要清理的垃圾文件后缀利用遍历放到了m_FilterList中,那么现在就是将它取出来的时候了。利用//获取临时文件
char *szFilter = m_FilterList.GetNext(pos);
遍历这个POSITION结构体中的所有元素,找到我们自己选中的需要清理的垃圾文件的后缀。
最后符合条件的话就输出来,放到列表框中。