MFC实现递归遍历文件夹内的所有文件夹和文件
2016-02-24 10:07
661 查看
[摘要]
为了简化自己的工作,所以就用MFC快速做了递归遍历文件夹内所有文件夹和文件的功能。因为这个功能非常实用,非常有必要总结出来供大家参考。
使用MFC实现遍历一个文件夹下的所有目录和文件,使用CFileFind类即可。然而要得到一个文件夹下的所有文件,包括子文件夹下的所有文件,就要使用递归了。当然,不一定非得是递归,也可以用循环。只不过使用递归实现比较简单罢了。
使用CFileFind类来遍历,实际上就是调用成员函数FindFile找到一个头,然后循环调用成员函数FindNextFile来枚举文件夹下的所有文件和文件夹。在文件夹中,包含了各种你没有看到的文件夹,如当前文件夹.和上一级文件夹..,以及隐藏的卷目录等等。而我们只是遍历用户目录,所以要将这些目录排除掉。
下面是判断找到的文件的类型的函数,其中,文件夹也是文件的一种,所以文件夹也是文件哦。CFileFind类中判断文件类型的成员函数如下:
IsDots():判断文件是否为当前目录.或者为上级目录..
IsHidden():判断文件是否带有隐藏属性,即隐藏的文件。
IsSystem():判断文件是否为系统文件。
IsTemporary():判断文件是否为临时文件。
IsReadOnly():判断文件是否为只读文件。
IsDirectory():判读文件是否为文件夹。
当然,还有其他几个,就不再列举说明了。你可以查看MSDN来看其他的成员函数说明。这些文件是我们需要过滤的,不是我们的文件类型,不应该列入我们遍历得到的文件列表中。
只要找到的文件不为空,表示是有效的文件,如果找到的文件是空,表示遍历完毕。我们使用递归遍历,就是在找到文件夹的时候,马上就去遍历文件夹,使用的是深度优先遍历方式。
我们使用一个vector容器,来存储遍历得到的文件的路径。如果得到的是文件的路径,就直接进入容器存储起来,如果是文件夹,则作为递归传入的子文件夹的路径,来遍历子文件夹。递归的关键就是需要一个终止条件,否则无限递归则会导致栈崩溃。我们的终止条件就是循环中遍历文件结束,返回空,从而结束循环,退出一级目录,继续上一级目录,如此可以终结递归。
我已经将递归遍历代码封装为一个函数,可以直接使用。代码如下:
如果你想改函数的名称,记得将函数里递归的调用名字一起改。还可以自己加入其它的文件类型判断,去掉不想过滤的文件类型。不过基本骨架就是这样的。各种实现方式都差不多,基于这个结构可以写出各种版本的,比如C/C++语言版的直接调用API,MFC版本,QT版本,Java版本,各种版本无非就是包装了API的工作方式,没什么。搞懂了这个流程,各种版本你也会写了。
为了简化自己的工作,所以就用MFC快速做了递归遍历文件夹内所有文件夹和文件的功能。因为这个功能非常实用,非常有必要总结出来供大家参考。
使用MFC实现遍历一个文件夹下的所有目录和文件,使用CFileFind类即可。然而要得到一个文件夹下的所有文件,包括子文件夹下的所有文件,就要使用递归了。当然,不一定非得是递归,也可以用循环。只不过使用递归实现比较简单罢了。
使用CFileFind类来遍历,实际上就是调用成员函数FindFile找到一个头,然后循环调用成员函数FindNextFile来枚举文件夹下的所有文件和文件夹。在文件夹中,包含了各种你没有看到的文件夹,如当前文件夹.和上一级文件夹..,以及隐藏的卷目录等等。而我们只是遍历用户目录,所以要将这些目录排除掉。
下面是判断找到的文件的类型的函数,其中,文件夹也是文件的一种,所以文件夹也是文件哦。CFileFind类中判断文件类型的成员函数如下:
IsDots():判断文件是否为当前目录.或者为上级目录..
IsHidden():判断文件是否带有隐藏属性,即隐藏的文件。
IsSystem():判断文件是否为系统文件。
IsTemporary():判断文件是否为临时文件。
IsReadOnly():判断文件是否为只读文件。
IsDirectory():判读文件是否为文件夹。
当然,还有其他几个,就不再列举说明了。你可以查看MSDN来看其他的成员函数说明。这些文件是我们需要过滤的,不是我们的文件类型,不应该列入我们遍历得到的文件列表中。
只要找到的文件不为空,表示是有效的文件,如果找到的文件是空,表示遍历完毕。我们使用递归遍历,就是在找到文件夹的时候,马上就去遍历文件夹,使用的是深度优先遍历方式。
我们使用一个vector容器,来存储遍历得到的文件的路径。如果得到的是文件的路径,就直接进入容器存储起来,如果是文件夹,则作为递归传入的子文件夹的路径,来遍历子文件夹。递归的关键就是需要一个终止条件,否则无限递归则会导致栈崩溃。我们的终止条件就是循环中遍历文件结束,返回空,从而结束循环,退出一级目录,继续上一级目录,如此可以终结递归。
我已经将递归遍历代码封装为一个函数,可以直接使用。代码如下:
void GetFilePath(vector<CString>& vFilePathList,CString strDir) { CFileFind finder; BOOL isNotEmpty = finder.FindFile(strDir+_T("*.*"));//总文件夹,开始遍历 while(isNotEmpty) { isNotEmpty = finder.FindNextFile();//查找文件 CString filename = finder.GetFilePath();//获取文件的路径,可能是文件夹,可能是文件 if (!(finder.IsDirectory())) { //如果是文件则加入文件列表 vFilePathList.push_back(filename);//将一个文件路径加入容器 } else { //递归遍历用户文件夹,跳过非用户文件夹 if(!(finder.IsDots()||finder.IsHidden()||finder.IsSystem()||finder.IsTemporary()||finder.IsReadOnly())) { GetFilePath(vFilePathList,filename+_T("/")); } } } }
如果你想改函数的名称,记得将函数里递归的调用名字一起改。还可以自己加入其它的文件类型判断,去掉不想过滤的文件类型。不过基本骨架就是这样的。各种实现方式都差不多,基于这个结构可以写出各种版本的,比如C/C++语言版的直接调用API,MFC版本,QT版本,Java版本,各种版本无非就是包装了API的工作方式,没什么。搞懂了这个流程,各种版本你也会写了。
相关文章推荐
- 降低页面加载时间
- Slim Span(Kruskal)
- 问卷调查
- 日期类型和字符转类型之间的最简单转换方法
- win32程序启用控制台
- drools
- OpenCV命名规则
- 对广告的处理
- CART算法
- @SuppressWarnings含义
- C++ inline 函数
- hive UDF 提取文本中的地名
- javascript parseInt函数详解
- RIOT 基于CC2538cb套件学习2,编译测试default和helloword
- Ubuntu的目录与第三方库
- iOS开发——遍历目录,获取文件名列表
- Java中Comparable和Comparator实现对象比较
- 使用js获取表单中各个name的值
- 两种状态分别DP+分类讨论(2577)
- SQLite的管理与C#应用