#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;
}