最近,在做毕业设计时,遇到遍历目录下所有文件的问题。具体情境是这样的:通过读取配置文件,获得需要访问的目录路径,该目录包含N层子目录和M个文件。然后需要遍历每个文件。对该问题的文件目录操作,Windows API提供了两个相关函数,FindFirstFile 和FindNextFile,使用它们写一个递归函数,就可以很好的解决这个问题了。代码如下:
void processAllDir( const char *path ) {
WIN32_FIND_DATA FindFileData; //该结构用来保存文件目录信息
HANDLE hFind; //保存文件查找的句柄
char path_search[MAX_PATH]; //存储查找目录路径
hFind = FindFirstFile( path, &FindFileData ); //查找path目录里的第一个文件,并把结果保存在FindFileData结构体里
if( hFind == INVALID_HANDLE_VALUE ) //判断查找是否成功
return;
if( FindFileData.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY ) { //判断是否为目录
if( FindFileData.cFileName[0] != '.' ) { //判断是否为“.”和“..”目录
strcpy( path_search, path ); //不是的话,把当前查找目录,copy到path_search
path_search[strlen(path_search)-1] = '\0'; //path形式为“D:\a\*”,此处去掉"*"
strcat( path_search, FindFileData.cFileName ); //连接当前查找到的目录名
strcat( path_search, "\\\*"); //处理为“D:\a\b\*”的形式
processAllDir( path_search ); //递归调用,进入下一级目录
_chdir( path ); //递归处理完,返回上一级目录
}
}
else { //如果不是目录,直接进行处理
strcpy( path_search, path );
path_search[strlen(path_search)-1] = '\0';
strcat( path_search, FindFileData.cFileName );
process( path_search ); //调用处理函数
}
while( FindNextFile( hFind, &FindFileData) ) { //继续处理下一个目录或文件
if( FindFileData.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY ) {
if( FindFileData.cFileName[0] != '.' ) {
strcpy( path_search, path );
path_search[strlen(path_search)-1] = '\0';
strcat( path_search, FindFileData.cFileName );
strcat( path_search, "\\\*");
processAllDir( path_search );
_chdir( path );
}
}
else {
strcpy( path_search, path );
path_search[strlen(path_search)-1] = '\0';
strcat( path_search, FindFileData.cFileName );
process( path_search );
}
}
FindClose( hFind ); //关闭文件查找句柄
}
几个值得注意的问题是:
1、windows路径使用 “\” 分割,在C/C++里,是转义字符的意思,所以得用 "\\" 表示 '\' ;
2、另外,msdn里有说到,查找目录“C:\abc”里的文件应该用"C:\abc\*"的形式。
3、网上有用 _chdir( FindFileData.cFileName ) 设置工作目录,这样的方式,实际上使用的是当前工作目录。如果遍历的不是当前工作目录,那会南辕北辙。所以,使用
strcpy( path_search, path );
path_search[strlen(path_search)-1] = '\0';
strcat( path_search, FindFileData.cFileName );
strcat( path_search, "\\\*");
来自己拼装下次遍历的目录。