一个文件遍历小函数的设计

之前写过 关于 win32 下磁盘的遍历方法,URL:http://blog.csdn.net/magictong/archive/2008/08/07/2784420.aspx,下面是将里面实现的磁盘遍历函数重新设计了一下,因为磁盘遍历,文件夹遍历在很多时候还是很常见的,为了不修改遍历的函数体,我将处理文件的部分交由一个回调函数去处理,这样的话,你甚至可以把下面的代码写在dll里面,需要进行文件遍历的地方,只要实现一个回调函数传进去就可以了。

 

函数声明:

  1. // ------------------------------------------------------------------------- 
  2. // 函数       : ScanDirectory 
  3. // 功能       : 遍历一个目录,传入一个函数指针 
  4. // 返回值  : BOOL  
  5. // 参数       : const TCHAR *pszPath                      传入路径 
  6. // 参数       : LPSCANDISK_START_ROUTINE lpFunAddress     函数指针回调指针 
  7. // 参数       : PVOID lpParam                             回调函数参数 
  8. // 参数       : BOOL bIsRecur/* = TRUE*/                  是否递归 
  9. // 附注       : 回调函数原型 DWORD WINAPI ScanProc(TCHAR *pFilePath, LPVOID lpParameter); 
  10. //            回调函数的第一个参数是扫描到一个文件的全名 
  11. // ------------------------------------------------------------------------- 
  12. typedef DWORD (WINAPI *LPSCANDISK_START_ROUTINE)(TCHAR *pFilePath, LPVOID lpParameter);
  13. BOOL ScanDirectory
  14. (const TCHAR *pszPath, LPSCANDISK_START_ROUTINE lpFunAddress, PVOID lpParam, BOOL bIsRecur = TRUE)

 

函数实现:

  1. // ------------------------------------------------------------------------- 
  2. // 函数       : ScanDirectory 
  3. // 功能       : 遍历一个目录,传入一个函数指针 
  4. // 返回值  : BOOL  
  5. // 参数       : const TCHAR *pszPath                      传入路径 
  6. // 参数       : LPSCANDISK_START_ROUTINE lpFunAddress     函数指针回调指针 
  7. // 参数       : PVOID lpParam                             回调函数参数 
  8. // 参数       : BOOL bIsRecur/* = TRUE*/                  是否递归 
  9. // 附注       : 回调函数原型 DWORD WINAPI ScanProc(TCHAR *pFilePath, LPVOID lpParameter); 
  10. //            回调函数的第一个参数是扫描到一个文件的全名 
  11. // ------------------------------------------------------------------------- 
  12. BOOL ScanDirectory(const TCHAR *pszPath, LPSCANDISK_START_ROUTINE lpFunAddress, PVOID lpParam, BOOL bIsRecur/* = TRUE*/)
  13. {
  14.     BOOL bRet = FALSE;
  15.     TCHAR *s = NULL;
  16.     HANDLE hFind = NULL;
  17.     WIN32_FIND_DATA fd = {0};
  18.     TCHAR szFileName[MAX_PATH] = TEXT("");
  19.     ::lstrcpy(szFileName, pszPath);
  20.     s = szFileName + ::lstrlen(szFileName);
  21.     if (*(s-1) != TEXT('//'))
  22.         *s++ = TEXT('//');
  23.     ::lstrcpy(s, TEXT("*.*"));
  24.     hFind = FindFirstFile(szFileName, &fd);
  25.     if (hFind == INVALID_HANDLE_VALUE)
  26.         goto Exit0;
  27.     do 
  28.     {
  29.         // 过滤 
  30.         if (::lstrcmpi(TEXT("."), fd.cFileName) == 0 || ::lstrcmpi(TEXT(".."), fd.cFileName) == 0)
  31.             continue;
  32.         ::lstrcpy(s, fd.cFileName);
  33.         *(s + ::lstrlen(fd.cFileName)) = L'/0';
  34.         // 如果是文件夹则递归 
  35.         if ((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && bIsRecur)
  36.         {
  37.             ScanDirectory(szFileName, lpFunAddress, lpParam, bIsRecur);
  38.         }
  39.         else
  40.         {
  41.             // 对文件进行处理 
  42.             if (lpFunAddress)
  43.                 lpFunAddress(szFileName, lpParam);
  44.         }
  45.     }while(::FindNextFile(hFind, &fd));
  46.     bRet = TRUE;
  47. Exit0:
  48.     if( hFind != INVALID_HANDLE_VALUE )
  49.     {
  50.         ::FindClose( hFind );
  51.         hFind = NULL;
  52.     }
  53.     return bRet;
  54. }

不过这样的实现有个小缺陷,文件特别多的话,效率会比较低,因为每一个文件都调用了一次回调函数,其实接口还可以设计一个过滤器出来,让扫描函数只对我们感兴趣的文件进行回调,再就是文件夹的处理,也可以进行回调,具体怎么做大家也可以练练手,呵呵,欢迎交流。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值