当前位置导航:炫浪网>>网络学院>>编程开发>>C++教程>>C++进阶与实例

文件遍历小函数的设计实例

   之前写过 关于 win32 下磁盘的遍历方法,下面是将里面实现的磁盘遍历函数重新设计了一下,因为磁盘遍历,文件夹遍历在很多时候还是很常见的,为了不修改遍历的函数体,我将处理文件的部分交由一个回调函数去处理,这样的话,你甚至可以把下面的代码写在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;
}

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