C/C++:遍历子目录,枚举文件,FindFirstFile + FindNextFile
来源:互联网 发布:ubuntu查看光纤卡wwn? 编辑:程序博客网 时间:2024/06/06 01:25
转自:http://blog.csdn.net/liigo/article/details/4548577
平时写程序时经常会用到的遍历子目录枚举文件的功能,用 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);
- //如果是.或..
- 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; }
- }
以下是应用示例代码:incopy
- 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;
- }
- 用一下代码比较容易看懂:
void BrowseCurrentDir(CString strDir) {CFileFind finder;CString strPath;CString strName;if (strDir.Right(1) != _T("\\")) {strDir += _T("\\");}strDir += _T("*.*");BOOL bWorking = finder.FindFile(strDir);while (bWorking) {bWorking = finder.FindNextFile();if (finder.IsDots()) {continue;}if (finder.IsDirectory()) {strPath = finder.GetFilePath();//strName = finder.GetFileName();//ODS(strPath);BrowseCurrentDir(strPath); //递归调用} else {strPath = finder.GetFilePath();strName = finder.GetFileName();//ODS(strPath);//ODS(_T("fileName: ") + strName);}}finder.Close();}
- C/C++:遍历子目录,枚举文件,FindFirstFile + FindNextFile
- C/C++:遍历子目录,枚举文件,FindFirstFile + FindNextFile
- C/C++:遍历子目录,枚举文件,FindFirstFile + FindNextFile
- c#调用api(FindFirstFile,FindNextFile)高效遍历目录文件
- 利用FindFirstFile和FindNextFile查找文件或遍历文件夹
- MFC FindFirstFile, FindNextFile 用法: 遍历目录下的文件
- C/C++ 利用FindFirstFile()和FindNextFile() 历遍指定目录的所有文件
- C/C++ 利用FindFirstFile()和FindNextFile() 历遍指定目录的所有文件
- 使用FindFirstFile和FindNextFile查找某个目录下的所有文件(包括子目录)
- 使用FindFirstFile和FindNextFile查找某个目录下的所有文件(包括子目录)
- 使用FindFirstFile和FindNextFile查找某个目录下的所有文件(包括子目录)
- 使用FindFirstFile和FindNextFile查找某个目录下的所有文件(包括子目录)
- 使用FindFirstFile,FindNextFile遍历一个文件夹
- 使用FindFirstFile,FindNextFile遍历一个文件夹
- 使用FindFirstFile,FindNextFile遍历一个文件夹
- 使用FindFirstFile,FindNextFile遍历一个文件夹
- 用FindFirstFile和FindNextFile遍历一个文件夹
- 使用FindFirstFile,FindNextFile遍历一个文件夹
- PHP 中 include和require的区别
- android 分辨率自适应
- android图片加载内存优化方法,有效解决大图片内存溢出(oom)
- 四个 void swap(int&,int&) 函数
- android异常小记
- C/C++:遍历子目录,枚举文件,FindFirstFile + FindNextFile
- MDX语句之:ParallelPeriod
- Huffman
- base64编码
- kill和kill -9
- 动态设置Activity背景图
- Java JSON解析的两种常用方式
- Andorid 网络流量统计
- mail.log的一个文档中读取并过滤出mail地址