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


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

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

                                                                   界面图

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

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

    (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++
  • 相关阅读:
    LeetCode算法题-Reverse String II(Java实现)
    LeetCode算法题-Convert BST to Greater Tree(Java实现)
    LeetCode算法题-K-diff Pairs in an Array(Java实现)
    LeetCode算法题-Minimum Absolute Difference in BST(Java实现)
    基于Bootstrap和Knockout.js的ASP.NET MVC开发实战 关于 拦截器的 学习 部分
    基于bootstrap和knockoutjs使用 mvc 查询
    Kindle Unlimited 上线的最热书单
    基于Bootstrap和Knockout.js的ASP.NET MVC开发实战
    程序员的数学
    数学女孩
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/2974769.html
Copyright © 2020-2023  润新知