中国IT动力,最新最全的IT技术教程
最新100篇 | 推荐100篇 | 专题100篇 | 排行榜 | 搜索 | 在线API文档
首 页 | 程序开发 | 操作系统 | 软件应用 | 图形图象 | 网络应用 | 精文荟萃 | 教育认证 | 硬件维护 | 未整理篇 | 站长教程
ASP JS PHP工程 ASP.NET 网站建设 UML J2EESUN .NET VC VB VFP 网络维护 数据库 DB2 SQL2000 Oracle Mysql
服务器 Win2000 Office C DreamWeaver FireWorks Flash PhotoShop 上网宝典 CorelDraw 协议大全 网络安全 微软认证
硬件维护  CPU  主板  硬盘  内存  显卡  显示器  键盘鼠标  声卡音箱  打印机  机箱电源  BIOS  网卡  C#  Java  Delphi  vs.net2005
  当前位置:> 程序开发 > 编程语言 > Visual C++ > 文件系统
运用多线程技术实现文件的快速搜索
作者:未知 时间:2005-07-20 14:21 出处:VC知识库 责编:chinaitpower
              摘要:运用多线程技术实现文件的快速搜索

运用多线程技术实现文件的快速搜索
作者:四川工业大学 姜勇道

下载本文配套源代码

从一名初学者到如今一名熟练的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<m_strPathArray.GetSize();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环境中编译通过。

作者信息:
通讯地址:华中科技大学模具国家重点实验室 邮编430074
电话:027-87543492
电邮:jiangyongdao@sina.com
关闭本页
 
首页 | 投资与合作 | 服务条款 | 隐私政策 | 收藏本站 | 设为首页 | 新用户注册 | 免责声明 | 使用帮助
Copyright ©2005-2008 chinaitpower.com All rights reserved. www.chinaitpower.com 版权所有