emmmm,这个文件搜索也有很多种的,我简单说下windows平台的吧。对mfc熟悉的可以用这个类CFileFind,熟悉Win32API的嘛,就可以用我下面提供的方法了,不过也不是很好,希望有更好的解决办法的伙伴在评论区留下建议。
1 线程的启动方式,例程上面用的是AfxBeginThread,后来想想,要不改成标准库中的线程函数试试看,还可以。
2 涉及到标准库中线程函数的封装,其实也没那个必要,就是玩玩。下面是我封装的一个放飞自我的线程。主线程中最好有变量控制来等待线程结束,否则可能会出问题。
template <class _Fn, class... _Args> std::thread::id BeginThread_DeTach(_Fn _Fx, _Args... _Argx)
{
std::thread tx(_Fx, _Argx...);
tx.detach();
return tx.get_id();
}
3 用起来也是很简单的,直接用就好了。和AfxBeginThread差不多。
BeginThread_DeTach(SearchFileThread, &m_param);
4 下面是我的线程执行代码Windows下的多线程文件搜索。
#include <afxmt.h>
#include <string>
#include <vector>
#include <thread>
#include <iostream>
using namespace std;
typedef struct THREADPARAM //线程参数结构体
{
std::string strPath; //路径名
std::string strFileName; //文件名
struct THREADPARAM *pSelf; //自身的指针
}MyTHREADPARAM;
std::vector<std::string> vstrSearchResult;//搜索的文件结果
MyTHREADPARAM m_param;//线程函数参数
CMutex m_mutexThreadCount, m_mutexFileCount, m_mutexThreadParam, m_mutexPath;
UINT uThreadCount = 0;//线程数目初始化为0
int nFileCount = 0;//找到文件的数量
CEvent g_FinishEvent; //事件对象
template <class _Fn, class... _Args> std::thread::id BeginThread_DeTach(_Fn _Fx, _Args... _Argx)
{
std::thread tx(_Fx, _Argx...);
tx.detach();
return tx.get_id();
}
UINT SearchFileThread(LPVOID pParam)//工作线程入口函数
{
m_mutexThreadParam.Lock();
MyTHREADPARAM * m_pParam = (MyTHREADPARAM *)pParam;
std::string strPath = m_pParam->strPath;
std::string strFileName = m_pParam->strFileName;
m_mutexThreadParam.Unlock();
m_mutexThreadCount.Lock();
uThreadCount++;
m_mutexThreadCount.Unlock();
HANDLE hFile;
WIN32_FIND_DATAA *pInfo = new WIN32_FIND_DATAA;
hFile = ::FindFirstFileA((strPath + "\\*.*").c_str(), pInfo);
if (hFile == INVALID_HANDLE_VALUE)//未找到文件或文件夹
{
delete pInfo;
m_mutexThreadCount.Lock();
uThreadCount--;//线程即将关闭
if (uThreadCount == 0)
g_FinishEvent.SetEvent(); //检查完成,路径错误返回
m_mutexThreadCount.Unlock();
return 0;
}
do {
if (pInfo->cFileName[0] == '.')
continue;
char cFileName[MAX_PATH];
strcpy(cFileName, pInfo->cFileName);
//LOG(cFileName);
std::string strFile = cFileName;
if (pInfo->dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY)//如果得到的是文件夹
{
m_mutexThreadParam.Lock();
MyTHREADPARAM *ptemp = new MyTHREADPARAM;
ptemp->pSelf = ptemp;
ptemp->strFileName = strFileName;
ptemp->strPath = strPath + "\\" + strFile;//将文件夹路径传给线程函数参数
m_mutexThreadParam.Unlock();
// AfxBeginThread(SearchFileThread, ptemp, THREAD_PRIORITY_NORMAL);//开始一个新的工作线程
BeginThread_DeTach(SearchFileThread, ptemp);
//tx.detach();
}
else//获取的是文件
{
if (strFile == strFileName)//找到要搜索的文件
{
m_mutexFileCount.Lock();
nFileCount++;//文件数目加1
m_mutexFileCount.Unlock();
m_mutexPath.Lock();
OutputDebugStringA(strPath.c_str());
std::string strFilePathName;
strFilePathName = strPath + "\\" + strFile;//文件路径及名称
vstrSearchResult.push_back(strFilePathName);//向结果中添加一条路径
//LOG(strFilePathName);
m_mutexPath.Unlock();
}
}
} while (::FindNextFileA(hFile, pInfo));
::FindClose(hFile); //搜索完毕关闭文件句柄
delete pInfo;//释放内存
m_mutexThreadCount.Lock();
uThreadCount--;//工作线程即将结束
if (uThreadCount == 0)
g_FinishEvent.SetEvent(); //搜索完成
m_mutexThreadCount.Unlock();
if (m_pParam->pSelf)
{
delete m_pParam; //删除掉自己
}
return 0;
}
void PrintResult()
{
std::vector<std::string>::iterator Reoultiter;
for (Reoultiter = vstrSearchResult.begin();Reoultiter != vstrSearchResult.end();++Reoultiter)
{
cout << *Reoultiter << endl;
}
}
UINT StartSearchFileThread(std::string filePah, std::string fileName)//工作线程参数设置函数
{
vstrSearchResult.clear();
g_FinishEvent.ResetEvent();
m_param.pSelf = nullptr;
m_param.strPath = filePah;
m_param.strFileName = fileName;
//AfxBeginThread(SearchFileThread, &m_param, THREAD_PRIORITY_NORMAL);//创建工作线程
/*std::thread t(SearchFileThread, &m_param);
t.detach();*/
BeginThread_DeTach(SearchFileThread, &m_param);
WaitForSingleObject(g_FinishEvent.m_hObject, INFINITE); //无限期等待
PrintResult();
return 0;
}
int main()
{
StartSearchFileThread("E:\\\\", "hello.exe");
//AfxBeginThread(StartSearchFileThread, NULL, THREAD_PRIORITY_NORMAL);//创建工作线程
system("pause");
return 0;
}