多线程扫描文件夹中的文件(经典模型)

#pragma once struct CMyDirectoryNode : public CNoTrackObject { CMyDirectoryNode* pNext; TCHAR szDir[MAX_PATH]; }; struct CMyDir : public CNoTrackObject { CMyDir* pNext; TCHAR szDir[MAX_PATH]; }; class CMyRapidFinder { public: //CMyRapidFinder(void); virtual ~CMyRapidFinder(void); BOOL CheckFile(LPCTSTR lpszFileName); CMyRapidFinder(int nMaxThread = 1); int m_nResultCount; int m_nThreadCount; const int m_nMaxThread; CTypedSimpleList m_listDir; CTypedSimpleList m_listResult; TCHAR m_szMatchName[MAX_PATH]; HANDLE m_hDirEvent; HANDLE m_hExitEvent; CRITICAL_SECTION m_cs; CRITICAL_SECTION m_cs0; }; UINT FinderEntry(LPVOID lpParam); FILE* GetData(FILE* pFile, BYTE* szBuffer, int nBufferSize, int& nResultSize); BOOL HasNotAsscii(BYTE* szBuffer, int nBufferSize); BOOL FileHasNotAsscii(LPCTSTR szFilePathName);

 

#include "StdAfx.h" #include "MyRapidFinder.h" CMyRapidFinder::CMyRapidFinder(int nMaxThread) : m_nMaxThread(nMaxThread) { m_nResultCount = 0; m_nThreadCount = 0; m_szMatchName[0] =_T('/0'); m_listDir.Construct(offsetof(CMyDirectoryNode, pNext)); m_listResult.Construct(offsetof(CMyDir, pNext)); m_hDirEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL); m_hExitEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL); ::InitializeCriticalSection(&m_cs); ::InitializeCriticalSection(&m_cs0); } CMyRapidFinder::~CMyRapidFinder(void) { ::CloseHandle(m_hDirEvent); ::CloseHandle(m_hExitEvent); ::DeleteCriticalSection(&m_cs); ::DeleteCriticalSection(&m_cs0); } BOOL CMyRapidFinder::CheckFile(LPCTSTR lpszFileName) { BOOL bRet = FALSE; /* TCHAR szStr[MAX_PATH] = { 0 }; TCHAR szSearch[MAX_PATH] = { 0 }; _tcscpy(szStr, lpszFileName); _tcscpy(szSearch, m_szMatchName); _tcsupr(szStr); _tcsupr(szSearch); if (_tcsstr(szStr, szSearch) != NULL) { bRet = TRUE; } */ return bRet; } UINT FinderEntry(LPVOID lpParam) { CMyRapidFinder* pFinder = (CMyRapidFinder*)lpParam; CMyDirectoryNode* pNode = NULL; BOOL bActive = TRUE; while (TRUE) { ::EnterCriticalSection(&pFinder->m_cs); if (pFinder->m_listDir.IsEmpty()) { bActive = FALSE; } else { pNode = pFinder->m_listDir.GetHead(); pFinder->m_listDir.Remove(pNode); } ::LeaveCriticalSection(&pFinder->m_cs); if (!bActive) { ::EnterCriticalSection(&pFinder->m_cs); pFinder->m_nThreadCount--; if (0 == pFinder->m_nThreadCount) { ::LeaveCriticalSection(&pFinder->m_cs); break; } ::LeaveCriticalSection(&pFinder->m_cs); ::ResetEvent(pFinder->m_hDirEvent); ::WaitForSingleObject(pFinder->m_hDirEvent, INFINITE); ::EnterCriticalSection(&pFinder->m_cs); pFinder->m_nThreadCount++; ::LeaveCriticalSection(&pFinder->m_cs); bActive = TRUE; continue; } WIN32_FIND_DATA fileData; HANDLE hFindFile; if (pNode->szDir[_tcslen(pNode->szDir) - 1] != _T('//')) { _tcscat(pNode->szDir, _T("//")); } _tcscat(pNode->szDir, _T("*.*")); hFindFile = ::FindFirstFile(pNode->szDir, &fileData); if (hFindFile != INVALID_HANDLE_VALUE) { do { if (_T('.') == fileData.cFileName[0]) { continue; } if (fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { CMyDirectoryNode* p = new CMyDirectoryNode; _tcsncpy(p->szDir, pNode->szDir, _tcslen(pNode->szDir) - 3); _tcscat(p->szDir, fileData.cFileName); ::EnterCriticalSection(&pFinder->m_cs); pFinder->m_listDir.AddHead(p); ::LeaveCriticalSection(&pFinder->m_cs); ::SetEvent(pFinder->m_hDirEvent); } else { //对文件进行处理,应该设为回调函数,可以应对多种需求 //if (pFinder->CheckFile(fileData.cFileName)) TCHAR szTmp[256] = { 0 }; _tcsncpy(szTmp, pNode->szDir, _tcslen(pNode->szDir) - 3); _tcscat(szTmp, fileData.cFileName); if(FileHasNotAsscii(szTmp)) { CMyDir* pDir = new CMyDir; _tcsncpy(pDir->szDir, pNode->szDir, _tcslen(pNode->szDir) - 3); _tcscat(pDir->szDir, fileData.cFileName); ::EnterCriticalSection(&pFinder->m_cs0); pFinder->m_listResult.AddHead(pDir); ::LeaveCriticalSection(&pFinder->m_cs0); } } } while (::FindNextFile(hFindFile, &fileData)); } delete pNode; pNode = NULL; } ::SetEvent(pFinder->m_hDirEvent); if (::WaitForSingleObject(pFinder->m_hDirEvent, 0) != WAIT_TIMEOUT) { ::SetEvent(pFinder->m_hExitEvent); } return 0; } FILE* GetData(FILE* pFile, BYTE* szBuffer, int nBufferSize, int& nResultSize) { nResultSize = fread(szBuffer, 1, nBufferSize, pFile); return pFile; } BOOL HasNotAsscii(BYTE* szBuffer, int nBufferSize) { BOOL bRet = FALSE; for (int i = 0; i < nBufferSize; i++) { if (szBuffer[i] > 0x7F) { bRet = TRUE; break; } } return bRet; } BOOL FileHasNotAsscii(LPCTSTR szFilePathName) { BOOL bRet = FALSE; const int BUFSIZE = 1024 * 4; BYTE buffer[BUFSIZE] = { 0 }; int nRetSize = 0; FILE* pFile = _tfopen(szFilePathName, _T("rb")); if (pFile != NULL) { do { GetData(pFile, buffer, BUFSIZE, nRetSize); if (nRetSize > 0) { if (HasNotAsscii(buffer, nRetSize)) { bRet = TRUE; break; } } } while (nRetSize >= BUFSIZE); fclose(pFile); } return bRet; }

你可能感兴趣的:(算法修炼)