垃圾文件的扫描、显示和清理
垃圾文件的扫描、显示和清理
上一篇我们说明了程序的概述以及需求分析等,程序的初始化界面为:
界面图
下面我们就是开始代码实现了,下面先开始实现功能部分,即垃圾文件的扫描、显示和清理。
功能的分析与设计:垃圾清理功能主要包括文件遍历扫描、显示已扫描到的文件以及垃圾文件的删除清理等。用户需要一边进行文件扫描,另一边可以对已经扫描到的垃圾文件进行清理操作。文件扫描通常会占用大量的时间,为了提高垃圾清理的可靠性和效率,应该使用多线程开发技术,即将文件扫描的任务放置在一个单独的线程中即可
(1)创建一个基于对话框的工程,工程名称为“ClearTmpFile”。
(2)向对话框中添加静态文本框、按钮、组合框、列表框、进度条等控件,效果如下:
控件布局图
(3)在对话框类CClearTmpFileDlg中添加共有的主要数据成员,各成员功能见注释部分:
CList<CString, CString> m_fileExtList; // 记录需要查找临时文件扩展名
bool m_bThreadExit; // 线程是否退出
bool m_bFinding; // 是否查找进行中
HANDLE m_hThread; // 查找文件的线程句柄
HANDLE m_hThread2; // bmp旋转线程句柄
CString m_szCurDisk; // 查找的磁盘
HANDLE m_hEvent; // 事件对象,在对话框关闭时将提前结束查找
bool m_bContinue; // 判断暂停或继续按钮操作
DWORD GetDiskSize( char * strPath); // 获取磁盘容量(已使用的)
DWORD m_dwDiskVol; // 磁盘总容量大小,单位为KB
DWORD m_dwScanedVol; // 已扫描的文件的容量
DWORD m_dwScanedTmpFileVol; // 扫描到的临时文件的容量大小
DWORD m_dwScanedTmpFileNum; // 扫描到的临时文件的容量大小
(4)向对话框类中添加ResearchFile方法,判读指定的目录,将指定的垃圾文件类型显示在扫描结果列表中。
void CClearTmpFileDlg::ResearchFile( char * pszPath)
{
char szTmp[MAX_PATH]={ 0 }; // 定义一个临时字符数组
strcpy(szTmp,pszPath);
if (szTmp[strlen(szTmp)- 1 ]!= ' \\ ' ) // 将目录以“\\*.*”形式结尾
{
strcat(szTmp, " \\*.* " ); // 连接字符串
}
else
{
strcat(szTmp, " *.* " ); // 连接字符串
}
WIN32_FIND_DATA findData; // 定义一个文件查找数据结构
memset(&findData, 0 , sizeof (WIN32_FIND_DATA));
HANDLE hFind = FindFirstFile(szTmp,&findData); // 开始查找文件
// 由于查找是在线程中进行的,这里判读用户是否退出线程,如果是则提前结束线程函数 if(m_bThreadExit)
{
FindClose(hFind); // 关闭查找句柄
SetEvent(m_hEvent); // 设置事件为有信号
return ;
}
if (hFind != INVALID_HANDLE_VALUE) // 文件查找成功
{
while (FindNextFile(hFind,&findData)==TRUE) // 查找下一个文件
{ // 由于查找是在线程中进行的,这里判读用户是否退出线程,如果是则提前结束线程函数
if (m_bThreadExit)
{
FindClose(hFind); // 关闭查找句柄
SetEvent(m_hEvent); // 设置事件为有信号
return ;
}
// 如果文件不是一个目录
if (!(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
{
DWORD dwFileSize = (findData.nFileSizeHigh* (MAXDWORD+ 1 ) + findData.nFileSizeLow)/( 1024 ); // 获取文件大小,单位为KB
m_dwScanedVol += dwFileSize; // 累计已扫描文件的容量大小,单位为KB
// m_dwScanedVol = m_dwScanedVol/1024; // 单位转换为:MB
// 设置进度条进度
m_progressCtl.SetPos((m_dwScanedVol/ 1024 ));
char szFileName[MAX_PATH] = { 0 }; // 定义字符数组,存储完整的文件名
strcpy(szFileName,pszPath); // 获取完整文件名
if (szFileName[strlen(szFileName)- 1 ] != ' \\ ' )
{
strcat(szFileName, " \\ " );
}
strcat(szFileName,( char * )findData.cFileName);
if (IsTmpFile(szFileName)) // 判断szFileName是否是临时文件
{
m_dwScanedTmpFileVol += dwFileSize; // 累计扫描到的临时文件容量大小,单位为KB
m_dwScanedTmpFileNum ++; // 累计扫描到的临时文件的数目
m_listBoxResults.AddString((LPCTSTR)szFileName);
}
}
else // 如果文件是一个目录,则递归遍历该目录
{
if ((strcmp(( const char *)&findData.cFileName, " ... " )!= 0 ) &&
(strcmp(( const char *)&findData.cFileName, " .. " )!= 0 )&&
(strcmp(( const char *)&findData.cFileName, " . " )!= 0 ))
{
char szFileName[MAX_PATH]={ 0 };
strcpy(szFileName,pszPath); // 获取完整文件名
if (szFileName[strlen(szFileName)- 1 ]!= ' \\ ' )
{
strcat(szFileName, " \\ " );
}
strcat(szFileName,( char * )findData.cFileName);
// 由于查找是在线程中进行的,这里判读用户是否退出线程,如果是则提前结束线程函数
if (m_bThreadExit)
{
FindClose(hFind); // 关闭查找句柄
SetEvent(m_hEvent); // 设置事件为有信号
return ;
}
ResearchFile(szFileName); // 递归调用
}
}
}
}
FindClose(hFind); // 关闭文件查找句柄
}
(5)定义线程函数,用来单独执行扫描查找垃圾文件任务:
DWORD _stdcall FindTmpFile(LPVOID lpParameter)
{
CClearTmpFileDlg * pDlg = (CClearTmpFileDlg*) lpParameter; // 获取线程参数
WaitForSingleObject(pDlg->m_hEvent,INFINITE); // 等待事件有信号
CString dir = pDlg->m_szCurDisk.GetBuffer(); // 根据当前盘符目录磁盘目录
char *s = (LPSTR)(LPCTSTR)dir;
pDlg -> ResearchFile(s);
pDlg -> Restore();
pDlg ->ShowResultText(); // 显示扫描临时文件的数目和大小
// 恢复数据为初始状态
pDlg->m_dwScanedTmpFileVol = 0 ;
pDlg ->m_dwScanedTmpFileNum = 0 ;
pDlg -> m_fileExtList.RemoveAll();
return 0 ;
}
(6)处理“立即扫描”或“开始”按钮的单击事件,创建一个新的线程执行扫描文件的任务:
// 如果查找没有结束,则不允许开始新的文件查找
GetDlgItem(IDC_BEGIN)-> ShowWindow(SW_HIDE);
if (!m_bFinding && GetTmpExtName()) // 获取文件扩展名
{
GetDlgItem(IDC_PROGRESS1) ->ShowWindow(TRUE); // 显示进度条
GetDlgItem(IDC_LIST1)-> ShowWindow(SW_SHOW);
m_bThreadExit = FALSE;
m_bFinding = TRUE;
m_combox.GetWindowText(m_szCurDisk); // 获取当前盘符
// 初始化进度条相关数据
m_dwDiskVol =GetDiskSize((LPSTR)(LPCTSTR)m_szCurDisk); // 获取当前磁盘的容量大小(已使用的)
CString str;
str.Format(_T( " %d " ),m_dwDiskVol/( 1024 ));
double iSize = atoi(str);
m_progressCtl.SetRange32( 0 ,m_dwDiskVol/ 1024 ); // 初始化进度条,设置进度条的范围,范围为MB的数量
if (m_hEvent!= NULL)
{
CloseHandle(m_hEvent); // 关闭事件对象
m_hEvent = NULL;
}
m_listBoxResults.ResetContent(); // 清空查找结果列表
m_hEvent = CreateEvent(NULL,FALSE,TRUE,_T( " Event " )); // 创建事件对象
// 创建一个线程,开始执行线程函数
m_hThread = CreateThread(NULL, 0 ,FindTmpFile, this , 0 ,NULL);
m_hThread2 = CreateThread(NULL, 0 ,RotatingImg, this , 0 ,NULL);
UpdateData(FALSE);
(7)清理已扫描到的垃圾文件,即采用删除文件策略,使用DeleteFile()方法:
void CClearTmpFileDlg::OnBnClickedDelall()
{ // 删除已扫描到的垃圾文件
CString strDel;
CFile file;
for ( int i= 0 ;i<m_listBoxResults.GetCount();i ++ )
{
m_listBoxResults.GetText(i,strDel);
GetDlgItem(IDC_TEST) -> SetWindowText(strDel);
DeleteFile(strDel); // 删除指定路径的文件
}
m_listBoxResults.ResetContent();
GetDlgItem(IDC_TEST) ->SetWindowText(_T( " 清理完毕! " ));
GetDlgItem(IDC_LIST1) -> ShowWindow(SW_HIDE);
GetDlgItem(IDC_BEGIN) -> ShowWindow(SW_SHOW);
GetDlgItem(IDC_BEGIN) ->SetWindowText(_T( " 重新扫描 " ));
}
好了,到此差不多软件的主要功能部分都已经开发完毕,大家已经看出来了,功能部分很简单,就是对指定的文件格式进行扫描、显示和清理。下面将进行对软件界面的设计与开发。
分类: C/C++
标签: VC++ , MFC , 多线程 , 垃圾清理 , 临时文件 , 位图 , 按钮 , 用户界面
作者: Leo_wl
出处: http://HdhCmsTestcnblogs测试数据/Leo_wl/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
版权信息