之前写过 关于 win32 下磁盘的遍历方法,URL:http://blog.csdn.net/magictong/archive/2008/08/07/2784420.aspx,下面是将里面实现的磁盘遍历函数重新设计了一下,因为磁盘遍历,文件夹遍历在很多时候还是很常见的,为了不修改遍历的函数体,我将处理文件的部分交由一个回调函数去处理,这样的话,你甚至可以把下面的代码写在dll里面,需要进行文件遍历的地方,只要实现一个回调函数传进去就可以了。
函数声明:
- // -------------------------------------------------------------------------
- // 函数 : ScanDirectory
- // 功能 : 遍历一个目录,传入一个函数指针
- // 返回值 : BOOL
- // 参数 : const TCHAR *pszPath 传入路径
- // 参数 : LPSCANDISK_START_ROUTINE lpFunAddress 函数指针回调指针
- // 参数 : PVOID lpParam 回调函数参数
- // 参数 : BOOL bIsRecur/* = TRUE*/ 是否递归
- // 附注 : 回调函数原型 DWORD WINAPI ScanProc(TCHAR *pFilePath, LPVOID lpParameter);
- // 回调函数的第一个参数是扫描到一个文件的全名
- // -------------------------------------------------------------------------
- typedef DWORD (WINAPI *LPSCANDISK_START_ROUTINE)(TCHAR *pFilePath, LPVOID lpParameter);
- BOOL ScanDirectory
- (const TCHAR *pszPath, LPSCANDISK_START_ROUTINE lpFunAddress, PVOID lpParam, BOOL bIsRecur = TRUE)
函数实现:
- // -------------------------------------------------------------------------
- // 函数 : ScanDirectory
- // 功能 : 遍历一个目录,传入一个函数指针
- // 返回值 : BOOL
- // 参数 : const TCHAR *pszPath 传入路径
- // 参数 : LPSCANDISK_START_ROUTINE lpFunAddress 函数指针回调指针
- // 参数 : PVOID lpParam 回调函数参数
- // 参数 : BOOL bIsRecur/* = TRUE*/ 是否递归
- // 附注 : 回调函数原型 DWORD WINAPI ScanProc(TCHAR *pFilePath, LPVOID lpParameter);
- // 回调函数的第一个参数是扫描到一个文件的全名
- // -------------------------------------------------------------------------
- BOOL ScanDirectory(const TCHAR *pszPath, LPSCANDISK_START_ROUTINE lpFunAddress, PVOID lpParam, BOOL bIsRecur/* = TRUE*/)
- {
- BOOL bRet = FALSE;
- TCHAR *s = NULL;
- HANDLE hFind = NULL;
- WIN32_FIND_DATA fd = {0};
- TCHAR szFileName[MAX_PATH] = TEXT("");
- ::lstrcpy(szFileName, pszPath);
- s = szFileName + ::lstrlen(szFileName);
- if (*(s-1) != TEXT('//'))
- *s++ = TEXT('//');
- ::lstrcpy(s, TEXT("*.*"));
- hFind = FindFirstFile(szFileName, &fd);
- if (hFind == INVALID_HANDLE_VALUE)
- goto Exit0;
- do
- {
- // 过滤
- if (::lstrcmpi(TEXT("."), fd.cFileName) == 0 || ::lstrcmpi(TEXT(".."), fd.cFileName) == 0)
- continue;
- ::lstrcpy(s, fd.cFileName);
- *(s + ::lstrlen(fd.cFileName)) = L'/0';
- // 如果是文件夹则递归
- if ((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && bIsRecur)
- {
- ScanDirectory(szFileName, lpFunAddress, lpParam, bIsRecur);
- }
- else
- {
- // 对文件进行处理
- if (lpFunAddress)
- lpFunAddress(szFileName, lpParam);
- }
- }while(::FindNextFile(hFind, &fd));
- bRet = TRUE;
- Exit0:
- if( hFind != INVALID_HANDLE_VALUE )
- {
- ::FindClose( hFind );
- hFind = NULL;
- }
- return bRet;
- }
不过这样的实现有个小缺陷,文件特别多的话,效率会比较低,因为每一个文件都调用了一次回调函数,其实接口还可以设计一个过滤器出来,让扫描函数只对我们感兴趣的文件进行回调,再就是文件夹的处理,也可以进行回调,具体怎么做大家也可以练练手,呵呵,欢迎交流。