当前位置:C++技术网 > 资讯 > MFC实现递归遍历文件夹内的所有文件夹和文件

MFC实现递归遍历文件夹内的所有文件夹和文件

更新时间:2016-01-03 23:40:45浏览次数:1+次

    使用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的工作方式,没什么。搞懂了这个流程,各种版本你也会写了。