24,854
社区成员
发帖
与我相关
我的任务
分享
/**
* @brief 遍历一个目录下的所有文件,可递归子目录
* @author soulmachine@gmail.com
* @param[in] pszDirPath 目录的路径,末尾没有'\'
* @param[in] pszFilterPostfix 过滤后缀,如"\\*.*", "\\*.jpg"
* @param[in] bRecursive 是否递归子目录
* @param[in] pfnProcessFile 回调函数指针,用于处理单个文件
* @param[out] pParameter 传递给pfnProcessFile 的参数
* @return 返回文件总数,失败返回-1, 一般失败只发生在第一次 FindFirstFile。
* @note 本函数主要用FindFirstFile,FindNextFile实现。
* @remarks 本函数是用递归版本
*/
int TraverseDirectory(PCTSTR pszDirPath, PCTSTR pszFilterPostfix,
const BOOL bRecursive, int (*pfnProcessFile) \
(PCTSTR pszFilePath, PVOID pParameter), PVOID pParameter)
{
static int nFileCount = 0; //文件总数
WIN32_FIND_DATA findFileData; //保存当前找到的文件的属性
HANDLE hFind = INVALID_HANDLE_VALUE; //FindFirstFile返回的句柄
//当层函数的扫描路径,文件绝对路径或下层函数的目录路径
TCHAR szDirPath[MAX_PATH];
(void)_tcscpy(szDirPath,pszDirPath);
(void)_tcscat(szDirPath, pszFilterPostfix);
hFind = FindFirstFile(szDirPath, &findFileData);
if(INVALID_HANDLE_VALUE == hFind)
{
// FindFirstFile失败的原因:
// 文件夹是坏的
// 没有权限
nFileCount = -1;
ERROR_RETURN(FindFirstFile_Failed);
}
do
{
(void)_sntprintf(szDirPath, (size_t)MAX_PATH, TEXT("%s\\%s"), pszDirPath, findFileData.cFileName);
//如果不是目录
if((DWORD)0 == (findFileData.dwFileAttributes & (DWORD)FILE_ATTRIBUTE_DIRECTORY))
{
nFileCount++;
if(NULL != pfnProcessFile)
{
(void)pfnProcessFile(szDirPath, pParameter);
}
}
//如果是目录,但不是.和..,递归
else if(bRecursive && (findFileData.cFileName[0] != TEXT('.')))
{
(void)TraverseDirectory(szDirPath, pszFilterPostfix, bRecursive, pfnProcessFile, pParameter);
}
else
{
//是.和.. 则什么也不做
}
} while (FALSE != FindNextFile(hFind,&findFileData));
(void)FindClose(hFind);
FindFirstFile_Failed:
return nFileCount;
}
typedef struct tagPARAMETER
{
PCTSTR pszFilterPostfix;
BOOL bRecursive;
int (*pfnProcessFile) (PCTSTR pszFilePath, PVOID pParameter);
};