之前寫過 關(guān)于 win32 下磁盤的遍歷方法,下面是將里面實(shí)現(xiàn)的磁盤遍歷函數(shù)重新設(shè)計(jì)了一下,因?yàn)榇疟P遍歷,文件夾遍歷在很多時(shí)候還是很常見的,為了不修改遍歷的函數(shù)體,我將處理文件的部分交由一個(gè)回調(diào)函數(shù)去處理,這樣的話,你甚至可以把下面的代碼寫在dll里面,需要進(jìn)行文件遍歷的地方,只要實(shí)現(xiàn)一個(gè)回調(diào)函數(shù)傳進(jìn)去就可以了。
函數(shù)聲明:
// 函數(shù) : ScanDirectory
// 功能 : 遍歷一個(gè)目錄,傳入一個(gè)函數(shù)指針
// 返回值 : BOOL
// 參數(shù) : const TCHAR *pszPath 傳入路徑
// 參數(shù) : LPSCANDISK_START_ROUTINE lpFunAddress 函數(shù)指針回調(diào)指針
// 參數(shù) : PVOID lpParam 回調(diào)函數(shù)參數(shù)
// 參數(shù) : BOOL bIsRecur/* = TRUE*/ 是否遞歸
// 附注 : 回調(diào)函數(shù)原型 DWORD WINAPI ScanProc(TCHAR *pFilePath, LPVOID lpParameter);
// 回調(diào)函數(shù)的第一個(gè)參數(shù)是掃描到一個(gè)文件的全名typedef DWORD (WINAPI *LPSCANDISK_START_ROUTINE)(TCHAR *pFilePath, LPVOID lpParameter);
BOOL ScanDirectory
(const TCHAR *pszPath, LPSCANDISK_START_ROUTINE lpFunAddress, PVOID lpParam, BOOL bIsRecur = TRUE) 函數(shù)實(shí)現(xiàn): // 函數(shù) : ScanDirectory
// 功能 : 遍歷一個(gè)目錄,傳入一個(gè)函數(shù)指針
// 返回值 : BOOL
// 參數(shù) : const TCHAR *pszPath 傳入路徑
// 參數(shù) : LPSCANDISK_START_ROUTINE lpFunAddress 函數(shù)指針回調(diào)指針
// 參數(shù) : PVOID lpParam 回調(diào)函數(shù)參數(shù)
// 參數(shù) : BOOL bIsRecur/* = TRUE*/ 是否遞歸
// 附注 : 回調(diào)函數(shù)原型 DWORD WINAPI ScanProc(TCHAR *pFilePath, LPVOID lpParameter);
// 回調(diào)函數(shù)的第一個(gè)參數(shù)是掃描到一個(gè)文件的全名
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
{
// 對文件進(jìn)行處理
if (lpFunAddress)
lpFunAddress(szFileName, lpParam);
}
}while(::FindNextFile(hFind, &fd));
bRet = TRUE;
Exit0:
if( hFind != INVALID_HANDLE_VALUE )
{
::FindClose( hFind );
hFind = NULL;
}
return bRet;
}
不過這樣的實(shí)現(xiàn)有個(gè)小缺陷,文件特別多的話,效率會比較低,因?yàn)槊恳粋€(gè)文件都調(diào)用了一次回調(diào)函數(shù),其實(shí)接口還可以設(shè)計(jì)一個(gè)過濾器出來,讓掃描函數(shù)只對我們感興趣的文件進(jìn)行回調(diào),考試,大提示再就是文件夾的處理,也可以進(jìn)行回調(diào),具體怎么做大家也可以練練手
函數(shù)聲明:
// 函數(shù) : ScanDirectory
// 功能 : 遍歷一個(gè)目錄,傳入一個(gè)函數(shù)指針
// 返回值 : BOOL
// 參數(shù) : const TCHAR *pszPath 傳入路徑
// 參數(shù) : LPSCANDISK_START_ROUTINE lpFunAddress 函數(shù)指針回調(diào)指針
// 參數(shù) : PVOID lpParam 回調(diào)函數(shù)參數(shù)
// 參數(shù) : BOOL bIsRecur/* = TRUE*/ 是否遞歸
// 附注 : 回調(diào)函數(shù)原型 DWORD WINAPI ScanProc(TCHAR *pFilePath, LPVOID lpParameter);
// 回調(diào)函數(shù)的第一個(gè)參數(shù)是掃描到一個(gè)文件的全名typedef DWORD (WINAPI *LPSCANDISK_START_ROUTINE)(TCHAR *pFilePath, LPVOID lpParameter);
BOOL ScanDirectory
(const TCHAR *pszPath, LPSCANDISK_START_ROUTINE lpFunAddress, PVOID lpParam, BOOL bIsRecur = TRUE) 函數(shù)實(shí)現(xiàn): // 函數(shù) : ScanDirectory
// 功能 : 遍歷一個(gè)目錄,傳入一個(gè)函數(shù)指針
// 返回值 : BOOL
// 參數(shù) : const TCHAR *pszPath 傳入路徑
// 參數(shù) : LPSCANDISK_START_ROUTINE lpFunAddress 函數(shù)指針回調(diào)指針
// 參數(shù) : PVOID lpParam 回調(diào)函數(shù)參數(shù)
// 參數(shù) : BOOL bIsRecur/* = TRUE*/ 是否遞歸
// 附注 : 回調(diào)函數(shù)原型 DWORD WINAPI ScanProc(TCHAR *pFilePath, LPVOID lpParameter);
// 回調(diào)函數(shù)的第一個(gè)參數(shù)是掃描到一個(gè)文件的全名
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
{
// 對文件進(jìn)行處理
if (lpFunAddress)
lpFunAddress(szFileName, lpParam);
}
}while(::FindNextFile(hFind, &fd));
bRet = TRUE;
Exit0:
if( hFind != INVALID_HANDLE_VALUE )
{
::FindClose( hFind );
hFind = NULL;
}
return bRet;
}
不過這樣的實(shí)現(xiàn)有個(gè)小缺陷,文件特別多的話,效率會比較低,因?yàn)槊恳粋€(gè)文件都調(diào)用了一次回調(diào)函數(shù),其實(shí)接口還可以設(shè)計(jì)一個(gè)過濾器出來,讓掃描函數(shù)只對我們感興趣的文件進(jìn)行回調(diào),考試,大提示再就是文件夾的處理,也可以進(jìn)行回調(diào),具體怎么做大家也可以練練手