| 查看: 142 | 回复: 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 ] |
» 猜你喜欢
拟解决的关键科学问题还要不要写
已经有7人回复
存款400万可以在学校里躺平吗
已经有17人回复
请教限项目规定
已经有3人回复
基金委咋了?2026年的指南还没有出来?
已经有10人回复
基金申报
已经有6人回复
推荐一本书
已经有13人回复
国自然申请面上模板最新2026版出了吗?
已经有17人回复
纳米粒子粒径的测量
已经有8人回复
疑惑?
已经有5人回复
计算机、0854电子信息(085401-058412)调剂
已经有5人回复














回复此楼