多线程搜索文件工具

#ifndef _FIND_FILE_H_ 
#define _FIND_FILE_H_
#include <afxwin.h>
#include<queue>
struct CDirectoryNode:public CNoTrackObject
{
    char            m_szDir[MAX_PATH * 8];
};

class CRapidFinder
{
public:
    friend UINT FindEntry(LPVOID lpParam);
    CRapidFinder(int nMaxThread);
    ~CRapidFinder();
    BOOL CheckFile(LPCTSTR lpszFileName);
    CRITICAL_SECTION GetCriticalSection();
    void AddDirectoryNode(CDirectoryNode* node);
    void SetnThreadCount(int nCount);
    long  GetFindCount();
    HANDLE                     m_hExitEvent;

private:
    long m_nResultCount;
    int m_nThreadCount;
    std::queue<CDirectoryNode*> m_listDir;
    CRITICAL_SECTION           m_cs;
    const int                  m_nMaxThread;
    char                       m_szMatchName[MAX_PATH];
    HANDLE                     m_hDirEvent;
};
#endif

 

#include <string.h>
#include "FindFile.h"

CRapidFinder::CRapidFinder(int nMaxThread):m_nMaxThread(nMaxThread)
{
    m_nResultCount = 0;
    m_nThreadCount = 0;
    m_szMatchName[0] = '\0';
    while(!m_listDir.empty())
    {
        m_listDir.pop();
    }
    m_hDirEvent = CreateEvent(NULL, FALSE, FALSE, _T("DirEvent"));
    m_hExitEvent = CreateEvent(NULL, FALSE, FALSE, _T("ExitEvent"));
    ::InitializeCriticalSection(&m_cs);
}

CRapidFinder::~CRapidFinder()
{
    CloseHandle(m_hDirEvent);
    CloseHandle(m_hExitEvent);
    DeleteCriticalSection(&m_cs);
}

CRITICAL_SECTION CRapidFinder::GetCriticalSection()
{
    return m_cs;
}

BOOL CRapidFinder::CheckFile(LPCTSTR lpszFileName)
{
    char szChar[MAX_PATH];
    char szSearch[MAX_PATH * 8];
    strcpy_s(szSearch, m_szMatchName);
    strcpy_s(szChar, lpszFileName);
    _strupr(szChar);
    _strupr(szSearch);
    if (strstr(szChar, szSearch))
    {
        return TRUE;
    }
    return FALSE;
}

void CRapidFinder::AddDirectoryNode(CDirectoryNode* node)
{
    EnterCriticalSection(&m_cs);
    m_listDir.push(node);
    LeaveCriticalSection(&m_cs);
}

void CRapidFinder::SetnThreadCount(int nCount)
{
    EnterCriticalSection(&m_cs);
    m_nThreadCount = nCount;
    LeaveCriticalSection(&m_cs);
}

long CRapidFinder::GetFindCount()
{
    EnterCriticalSection(&m_cs);
    int nCount = m_nResultCount;
    LeaveCriticalSection(&m_cs);
    return nCount;
}

UINT FindEntry(LPVOID lpParam)
{
    CRapidFinder*       pFinder = (CRapidFinder*)lpParam;
    CDirectoryNode*     pNode = nullptr;
    BOOL                bActive = TRUE;
    while(1)
    {
        ::EnterCriticalSection(&pFinder->GetCriticalSection());
        if (pFinder->m_listDir.empty())
        {
            bActive = FALSE;
        }
        else
        {
           bActive = TRUE;
           pNode = pFinder->m_listDir.front();
           pFinder->m_listDir.pop();
        }
        ::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 hFinFile = INVALID_HANDLE_VALUE;
        if (pNode->m_szDir[strlen(pNode->m_szDir) -1 ] != '\\')
        {
            strcat_s(pNode->m_szDir, MAX_PATH *8, "\\");
        }
        strcat_s(pNode->m_szDir, MAX_PATH*8,  "*.*");

        hFinFile = FindFirstFile(pNode->m_szDir, &fileData);
        if (hFinFile != INVALID_HANDLE_VALUE)
        {
            do 
            {
                if (fileData.cFileName[0] == '.')
                {
                    continue;
                }
                if (fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
                {
                    CDirectoryNode* p = new CDirectoryNode;
                    strncpy_s(p->m_szDir, pNode->m_szDir, strlen(pNode->m_szDir) -3);
                    strcat_s(p->m_szDir, fileData.cFileName);
                    EnterCriticalSection(&pFinder->m_cs);
                    pFinder->m_listDir.push(p);
                    LeaveCriticalSection(&pFinder->m_cs);
                    SetEvent(pFinder->m_hDirEvent);
                }
                else
                {
                    if (pFinder->CheckFile(fileData.cFileName))
                    {
                        ::EnterCriticalSection(&pFinder->m_cs);
                        InterlockedIncrement((long*)&pFinder->m_nResultCount);
                        ::LeaveCriticalSection(&pFinder->m_cs);
                        printf("%s \n", fileData.cFileName);
                    } 
                }
            } while (::FindNextFile(hFinFile, &fileData));
        }
        delete pNode;
        pNode = nullptr;
    }
    SetEvent(pFinder->m_hDirEvent);
    if (WaitForSingleObject(pFinder->m_hDirEvent, 0) != WAIT_TIMEOUT)
    {
        SetEvent(pFinder->m_hExitEvent);
    }
    return 0;
}

void main()
{
    CRapidFinder* pFinder = new CRapidFinder(64);
    CDirectoryNode* pNode = new CDirectoryNode;

    char szPath[] = _T("C:\\");
    char szFile[] = _T("stdafx");

    strcpy_s(pNode->m_szDir, MAX_PATH*8, szPath);
    pFinder->AddDirectoryNode(pNode);
    for (int i = 0; i < 64; ++i)
    {
        AfxBeginThread(FindEntry, (LPVOID)pFinder);
    }

    WaitForSingleObject(pFinder->m_hExitEvent, INFINITE);

    printf("最终查找文件的个数:%d \n", pFinder->GetFindCount());

}

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值