24小时热门版块排行榜    

查看: 179  |  回复: 0
当前主题已经存档。

zsglly

木虫 (著名写手)

[交流] 运用多线程技术实现文件的快速搜索

从一名初学者到如今一名熟练的VC程序员,得益于VC知识库的帮助,一直想着该如何回报。现撰此文,一来略表心意,二来和VC爱好者交流。
操作系统一般都提供了文件搜索的功能,但采用的是顺序搜索,搜索效率很底。而且按此法编程十分烦琐,在目录层次很多时,往往不好处理。本文采用多线程技术实现文件的快速搜索,代码量很少,执行效率极高。
其基本思想其实很简单,就是找到一个目录就开辟一个线程,文件的话当然在线程内就处理了。这样实现了同步搜索,速度当然快起来了。


本文程序运行效果图

以下介绍VC具体实现:
一、 搜索用到两个win32的两个函数:


HANDLE FindFirstFile(LPCTSTR lpFileName,LPWIN32_FIND_DATA lpFindFileData );
BOOL FindNextFile( HANDLE hFindFile, LPWIN32_FIND_DATA lpFindFileData );

二、 建立线程函数
首先要定义线程的参数结构用于文件信息的传递:
typedef struct tagTHREADPARAM {
CString strPath;
CString strFileName;
}THREADPARAM  m_param;

因为线程要操纵全局变量,所以定义互斥体:CMutex m_mutexThreadCount,m_mutexThreadParam,m_mutexPath;
如果搜索完毕或搜索终止,要有事件通知,于是创建一个事件: CEvent m_event(FALSE,FALSE,NULL,NULL);
UINT uThreadCount=0;//产生的线程数
CStringArray m_strPathArray;//存放搜索到的文件路径数组
//线程函数
UINT GetFilePathThreadProc(LPVOID pParam)
{
if(pParam==NULL)
AfxEndThread(NULL);
THREADPARAM * m_pParam=(THREADPARAM *)pParam;
CString strPath=m_pParam->strPath;
CString strFileName=m_pParam->strFileName;
m_mutexThreadCount.Lock();
uThreadCount++;
m_mutexThreadCount.Unlock();
HANDLE hFile;
WIN32_FIND_DATA *pInfo=new WIN32_FIND_DATA;
hFile = ::FindFirstFile(strPath+"\\*.*",pInfo);
if(hFile==INVALID_HANDLE_VALUE)
{
delete pInfo;
m_mutexThreadCount.Lock();
uThreadCount--;
        //所有的线程完成,则激活事件,通知应用程序完成搜索(下同)
if(uThreadCount==0)
m_event.SetEvent();
m_mutexThreadCount.Unlock();
return 0;
}
do{
if(pInfo->cFileName[0]==''.'')
continue;
char cFileName[MAX_PATH];
strcpy(cFileName,pInfo->cFileName);
CString strFile=cFileName;
if(pInfo->dwFileAttributes==FILE_ATTRIBUTE_DIRECTORY)
{
    //如果是目录,则开辟新的搜索线程
m_mutexThreadParam.Lock();
m_param.strPath=strPath+"\\"+strFile;
m_param.strFileName=strFileName;
AfxBeginThread(GetFilePathThreadProc,&m_param, THREAD_PRIORITY_NORMAL);
m_mutexThreadParam.Unlock();
}
else
{
//如果是文件则直接与要搜索的文件比较
if(strFile==strFileName){
m_mutexPath.Lock();
m_strPathArray.Add(strPath+"\\"+strFile);
m_mutexPath.Unlock();
m_mutexThreadCount.Lock();
uThreadCount--;
if(uThreadCount==0)
m_event.SetEvent();
m_mutexThreadCount.Unlock();
return 0;
}
}
}
while(::FindNextFile( hFile,pInfo));
::FindClose(hFile);
delete pInfo;
m_mutexThreadCount.Lock();
uThreadCount--;
if(uThreadCount==0)
m_event.SetEvent();
m_mutexThreadCount.Unlock();
return 0;
}

三、 调用线程函数执行搜索 void GetFilePath()
{
m_event.ResetEvent();//将事件置为无信号状态
uThreadCount=0;
m_strPathArray.RemoveAll();
m_param.strPath=m_strPath;
m_param.strFileName=m_strFileName;
m_param.m_pListInfo=&m_ListInfo;
//启动线程  
AfxBeginThread(GetFilePathThreadProc,&m_param, THREAD_PRIORITY_NORMAL);  
//等待搜索完成或终止事件的发生
::WaitForSingleObject(m_event.m_hObject,INFINITE);  
if(m_strPathArray.GetUpperBound()==-1){
AfxMessageBox("没找到文件",MB_OK|MB_ICONINFORMATION);return;}
for(int i=0;i {
AfxMessageBox(m_strPathArray.GetAt(i),MB_OK|MB_ICONINFORMATION);
}
}

四、 如果想中途停止搜索,只需先将线程对象存放于一线程对象数组,当然每增加一个线程则添加一个线程对象到数组,每返回一个线程,则将该线程对象从数组中删除。这样在你想终止搜索时,可操作这些线程对象即可达到目的。具体调用两个函数: BOOL GetExitCodeThread(HANDLE hThread,LPDWORD lpExitCode);
BOOL TerminateThread(HANDLE hThread, DWORD dwExitCode);
BOOL GetExitCodeThread(
  HANDLE hThread,      // handle to the thread
  LPDWORD lpExitCode   // address to receive termination status
);
BOOL TerminateThread(
  HANDLE hThread,    // handle to thread
  DWORD dwExitCode   // exit code
);
程序实现的具体情况请参见源代码。本文在VC++6.0和Windows2000环境中编译通过。

[ Last edited by 幻影无痕 on 2006-11-29 at 07:47 ]
回复此楼
做人要厚道啊!厚道啊!
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖
相关版块跳转 我要订阅楼主 zsglly 的主题更新
普通表情 高级回复 (可上传附件)
最具人气热帖推荐 [查看全部] 作者 回/看 最后发表
[博后之家] 售SCI文章,我:8O5.5.1.O.54,科目齐全,可+急 +7 gy1nBQXYQJqL 2026-08-29 9/450 2026-08-31 01:15 by hZiFeudZyoGR
[硕博家园] 售SCI一区T0P文章,我:8.O.55.1.O.54,科目齐全,可+急 +4 gy1nBQXYQJqL 2026-08-29 8/400 2026-08-31 00:45 by hZiFeudZyoGR
[考研] 售一区SCI文章T0P,我:8O.551.O54,科目全,可十急 +7 ASdOkHsho7FD 2026-08-28 11/550 2026-08-31 00:32 by hZiFeudZyoGR
[考博] 售SCI-T0P文章,我:8O.5.5.1.O.54,科目齐全,可+急 +4 ASdOkHsho7FD 2026-08-28 7/350 2026-08-31 00:21 by hZiFeudZyoGR
[基金申请] 能否申诉? +4 echo8914667 2026-08-30 5/250 2026-08-30 21:11 by echo8914667
[考研] 售SCI一区文章,我:8.O.55.1.O.54,科目齐全,可伽急 +3 zICmwzsBXjbN 2026-08-29 5/250 2026-08-30 20:08 by hZiFeudZyoGR
[论文投稿] 售SCI一区T0P文章,我:8O.55.1.O.5.4,科目齐全,可+急 +3 jCd0dEvKHShX 2026-08-29 4/200 2026-08-30 19:57 by hZiFeudZyoGR
[找工作] 售SCI文章,我:8O5.5.1.O.54,科目齐全,可+急 +4 jCd0dEvKHShX 2026-08-29 5/250 2026-08-30 19:48 by hZiFeudZyoGR
[找工作] 售SCI一区T0P文章,我:8.O55.1.O.54,科目全,可十急 +3 jCd0dEvKHShX 2026-08-29 4/200 2026-08-30 19:35 by hZiFeudZyoGR
[考博] 售SCI一区T0P文章,我:8.O.55.1.O.5.4,科目全,可+急 +3 jCd0dEvKHShX 2026-08-29 3/150 2026-08-30 19:26 by hZiFeudZyoGR
[硕博家园] 售SCI一区T0P文章,我:8O.55.1.O.5.4,科目齐全,可+急 +3 jCd0dEvKHShX 2026-08-29 5/250 2026-08-30 19:23 by hZiFeudZyoGR
[考研] 售SCI一区文章,我:8.O.55.1.O.54,科目齐全,可伽急 +8 ASdOkHsho7FD 2026-08-28 12/600 2026-08-30 17:11 by hZiFeudZyoGR
[论文投稿] 售SCI一区T0P文章,我:8.O55.1.O.54,科目全,可十急 +6 ASdOkHsho7FD 2026-08-28 7/350 2026-08-30 17:03 by hZiFeudZyoGR
[公派出国] 售SCI一区T0P文章,我:8O.55.1.O.54,科目全,可伽急 +3 jCd0dEvKHShX 2026-08-29 5/250 2026-08-30 14:03 by GkCVyODlx4mR
[基金申请] 为什么资助数各大高校都创新高,自己申请怎么就这么难 +12 Kittylucky 2026-08-27 13/650 2026-08-29 00:04 by superceng
[基金申请] 为什么国自然不能直接公布 +4 bjdxyxy 2026-08-26 4/200 2026-08-26 13:12 by qingmu1201
[基金申请] 国际合作可查了,中了面上 (EPI+1)(金币+50) +18 Ldrop2023 2026-08-26 18/900 2026-08-26 11:15 by cmrandy
[基金申请] 项目信息和经费信息在系统里都可以看到了 +6 wittyboy 2026-08-26 14/700 2026-08-26 10:55 by wittyboy
[基金申请] 牛来!米来!面来! +8 beefly 2026-08-26 8/400 2026-08-26 08:37 by xuzhipiao
[基金申请] 在坚冰还盖着北海的时候,我看到了怒放的梅花。 (金币+10) +6 ziyangfang 2026-08-25 9/450 2026-08-25 20:26 by huagongfeihu
信息提示
请填处理意见