好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

垃圾文件的扫描、显示和清理

垃圾文件的扫描、显示和清理

垃圾文件的扫描、显示和清理

上一篇我们说明了程序的概述以及需求分析等,程序的初始化界面为:

                                                               界面图

下面我们就是开始代码实现了,下面先开始实现功能部分,即垃圾文件的扫描、显示和清理。

功能的分析与设计:垃圾清理功能主要包括文件遍历扫描、显示已扫描到的文件以及垃圾文件的删除清理等。用户需要一边进行文件扫描,另一边可以对已经扫描到的垃圾文件进行清理操作。文件扫描通常会占用大量的时间,为了提高垃圾清理的可靠性和效率,应该使用多线程开发技术,即将文件扫描的任务放置在一个单独的线程中即可

(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://www.cnblogs.com/Leo_wl/

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权信息

查看更多关于垃圾文件的扫描、显示和清理的详细内容...

  阅读:45次