程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> C/C++:遍歷子目錄,枚舉文件,FindFirstFile + FindNextFile

C/C++:遍歷子目錄,枚舉文件,FindFirstFile + FindNextFile

編輯:C++入門知識

 

平時寫程序時經常會用到的遍歷子目錄枚舉文件的功能,用Windows API 函數FindFirstFile() 和FindNextFile() 直接實現起來會相當繁瑣,有許多細節需要注意和記憶,要在短時間內寫出可以正常工作的、沒有BUG的、能夠遞歸遍歷多層子目錄並枚舉其中所有文件的程序代碼,不是一件輕松的事情。以下這個doFileEnumeration() 函數,是我(liigo)在Windows API 函數FindFirstFile() 和FindNextFile() 的基礎上封裝實現的,可以輕松自如的處理遍歷子目錄枚舉文件的任務,使用起來非常簡單,具有較高的實用價值。這個函數其實是我之前發布的易語言“輔助調試支持庫”(已開源至googlecode)中“枚舉文件”“枚舉子目錄”這兩條命令的底層實現函數。

  doFileEnumeration() 函數功能是實現枚舉文件和枚舉子目錄,支持遞歸處理多層子目錄嵌套的情況。它有五個參數:第一個參數lpPath指定欲遍歷的路徑(文件夾);第二個參數bRecursion指定是否遞歸處理子目錄;第三個參數bEnumFiles指定是枚舉文件還是枚舉子目錄;第四個參數pFunc為用戶回調函數,枚舉過程中每遇到一個文件或子目錄,都會調用它,並傳入這個文件或子目錄的完整路徑;第五個參數pUserData為用戶任意指定的數據,它也將被傳入用戶回調函數。用戶回調函數(EnumerateFunc)有兩個參數,一個是文件或子目錄的完整路徑(lpFileOrPath),一個是用戶自定義數據(pUserData),它被自動調用,用戶需在此函數中編碼處理代碼。

  這個函數經過我(liigo)的仔細設計,接口很簡潔,使用也方便。有意去除了FindFirstFile(Ex)/FindNextFile 中過濾文件名稱或屬性的部分功能,也是出於簡化接口的考慮,——在用戶回調函數中處理這些事情也是很容易的(在易語言中更容易)。在實現的細節上,重點是對子目錄和遞歸的處理。以下是完整的源代碼:

 

#include <windows.h>   

 

typedef BOOL (WINAPI *EnumerateFunc) (LPCSTR lpFileOrPath, void* pUserData);   

 

void doFileEnumeration(LPSTR lpPath, BOOL bRecursion, BOOL bEnumFiles, EnumerateFunc pFunc, void* pUserData)   

{   

     

    static BOOL s_bUserBreak = FALSE;   

    try{   

        //-------------------------------------------------------------------------   

        if(s_bUserBreak) return;   

         

        int len = strlen(lpPath);   

        if(lpPath==NULL || len<=0) return;   

         

        //NotifySys(NRS_DO_EVENTS, 0,0);   

         

        char path[MAX_PATH];   

        strcpy(path, lpPath);   

        if(lpPath[len-1] != '\\') strcat(path, "\\");   

        strcat(path, "*");   

         

        WIN32_FIND_DATA fd;   

        HANDLE hFindFile = FindFirstFile(path, &fd);   

        if(hFindFile == INVALID_HANDLE_VALUE)   

        {   

            ::FindClose(hFindFile); return;   

        }   

         

        char tempPath[MAX_PATH]; BOOL bUserReture=TRUE; BOOL bIsDirectory;   

         

        BOOL bFinish = FALSE;   

        while(!bFinish)   

        {   

            strcpy(tempPath, lpPath);   

            if(lpPath[len-1] != '\\') strcat(tempPath, "\\");   

            strcat(tempPath, fd.cFileName);   

             

            bIsDirectory = ((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0);   

             

            //如果是.或..    www.2cto.com

            if( bIsDirectory   

                && (strcmp(fd.cFileName, ".")==0 || strcmp(fd.cFileName, "..")==0))    

            {          

                bFinish = (FindNextFile(hFindFile, &fd) == FALSE);   

                continue;   

            }   

             

            if(pFunc && bEnumFiles!=bIsDirectory)   

            {   

                bUserReture = pFunc(tempPath, pUserData);   

                if(bUserReture==FALSE)   

                {   

                    s_bUserBreak = TRUE; ::FindClose(hFindFile); return;   

                }   

            }   

             

            //NotifySys(NRS_DO_EVENTS, 0,0);   

             

            if(bIsDirectory && bRecursion) //是子目錄   

            {   

                doFileEnumeration(tempPath, bRecursion, bEnumFiles, pFunc, pUserData);   

            }   

             

            bFinish = (FindNextFile(hFindFile, &fd) == FALSE);   

        }   

         

        ::FindClose(hFindFile);   

         

        //-------------------------------------------------------------------------   

    }catch(...){ ASSERT(0); return; }   

}   

 

BOOL WINAPI myEnumerateFunc(LPCSTR lpFileOrPath, void* pUserData)   

{   

    char* pdot;   

    if((pdot = strrchr(lpFileOrPath, '.')) && stricmp(pdot, ".mp3") == 0)   

    {   

        printf("%s\n", lpFileOrPath);   

    }   

    return TRUE;   

}   

 

int main()   

{   

    doFileEnumeration("C:\\Music", TRUE, TRUE, myEnumerateFunc, NULL);   

    return 0;   

}  

摘自 龍圖騰的博客

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved