24小时热门版块排行榜    

查看: 154  |  回复: 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 的主题更新
普通表情 高级回复 (可上传附件)
最具人气热帖推荐 [查看全部] 作者 回/看 最后发表
[考研] 考研复试调剂,过国家线的同学都可报名 +4 黑!在干嘛 2026-02-28 5/250 2026-03-02 16:48 by chock1337
[考研] 接收调剂 +4 津萌津萌 2026-03-02 7/350 2026-03-02 16:37 by 津萌津萌
[考研] 290求调剂 +5 ErMiao1020 2026-03-02 5/250 2026-03-02 16:36 by 无际的草原
[考研] 化工京区271求调剂 +4 11ing 2026-03-02 4/200 2026-03-02 15:47 by 杨杨杨紫
[考研] 0856化工专硕求调剂 +15 董boxing 2026-03-01 15/750 2026-03-02 15:06 by 晃晃不许晃
[考研] 290分材料工程085601求调剂 数二英一 +3 llx0610 2026-03-02 3/150 2026-03-02 14:15 by yc258
[考研] 272求调剂 +7 材紫有化 2026-02-28 7/350 2026-03-02 12:48 by 无际的草原
[考研] 275求调剂 +4 明远求学 2026-03-01 4/200 2026-03-02 12:45 by 无际的草原
[基金申请] 成果系统访问量大,请15分钟后再尝试。由此给您造成的不便,敬请谅解。 +5 xhuama 2026-03-02 5/250 2026-03-02 12:34 by stidwellNK
[考研] 264求调剂 +4 巴拉巴拉根556 2026-02-28 4/200 2026-03-02 10:48 by yuchj
[考研] 274求调剂 +3 cgyzqwn 2026-03-01 7/350 2026-03-02 10:38 by lature00
[考研] 275求调剂 +3 L-xin? 2026-03-01 6/300 2026-03-02 10:22 by 热情沙漠
[考研] 调剂 +3 13853210211 2026-03-02 4/200 2026-03-02 10:16 by 13853210211
[考研] 材料工程269求调剂 +3 白刺玫 2026-03-02 3/150 2026-03-02 09:25 by 一休哥FU
[考研] 材料复试调剂 +4 学材料的点 2026-03-01 5/250 2026-03-02 08:26 by houyaoxu
[基金申请] 成果系统访问量大,请一小时后再尝试。---NSFC啥时候好哦,已经两天这样了 +4 NSFC2026我来了 2026-02-28 4/200 2026-03-01 22:37 by 铁门栓
[考研] 298求调剂 +6 axyz3 2026-02-28 6/300 2026-03-01 19:00 by 18137688336
[考研] 0856材料求调剂 +4 麻辣鱿鱼 2026-02-28 4/200 2026-03-01 16:51 by caszguilin
[考研] 寻找调剂 +4 LYidhsjabdj 2026-02-28 4/200 2026-03-01 10:56 by sunny81
[高分子] 求环氧树脂研发1名 +3 孙xc 2026-02-25 11/550 2026-02-28 16:57 by ichall
信息提示
请填处理意见