学习MFC: 遍历指定文件夹下的所有文件并排序

MFC下遍历文件夹下的所有文件,借助于CString类和CFileFind类的便捷,代码如下:

只有一层文件结构

很多时候我们要处理的文件只在一个特定的文件夹下,且该路径下除了待处理的文件之外没有其他文件夹,这时情况比较简单,不需要迭代处理,直接按照下面的操作即可:

    CString filepath = _T("/path/to/folder/"); 
    CString filename = _T("");
    CString fullname = _T("");

    CFileFind find;
    BOOL IsFind = find.FindFile(filepath + _T("/*.*"));

    while (IsFind)
    {
        IsFind = find.FindNextFile();
        if (find.IsDots())
        {
            continue;
        }
        else
        {
            filename = find.GetFileName();
            fullname = filepath + filename;
            cout << fullname << endl;
        }
    }

多层文件结构

有时候我们处理的文件有多个文件结构,也就是说文件夹下面还有文件夹,这时候需要采用递归的方式遍历。举个例子,比如我们要处理一批后缀名为***.bmp***的文件,且这些文件在一个根目录下面的很多子目录下,那么我们可以这样处理:

void BroseAllFiles(CString filepath)
{
    //检测路径是否正确并添加必要信息
    if (filepath == _T(""))
    {
        return;
    }
    else 
    {
        if (filepath.Right(1) != _T(""))
        {
            filepath += _T("\\");
        }
        filepath += _T("*.*");
    }

    //递归枚举文件夹下的内容
    CFileFind find;
    CString strpath;
    CString str_fileName;
    CString fullname;
    BOOL IsFind = find.FindFile(filepath);

    while (IsFind)
    {
        IsFind = find.FindNextFile();
        strpath = find.GetFilePath();

        if (find.IsDirectory() && !find.IsDots())
        {
            BroseAllFiles(strpath);
        }
        else if (!find.IsDierctory() && !find.IsDots())
        {
            str_fileName = find.GetFileName();
            if (str_fileName.Right(3) == _T("bmp")) //如果后缀是bmp文件才处理
            {
                fullname = strpath + str_fileName;
                cout << fullname << endl;
            }
        }
        else 
        {
            continue;
        }
    }
}

注:这个函数是对照参考资料写的,没有经过实际验证,如果出错请自行修改。

排序

另一个问题是如果我们的文件是按照序号排列的,比如1.bmp, 2.bmp, ..., 10.bmp, ... 100.bmp, 当遍历完之后,发现结果会是这样:1.bmp, 10.bmp, 100.bmp, 2.bmp ... 9.bmp。因此我们需要给查找到的文件排个序。想法也很简单,如果你的文件名像上面给的例子一样命名,那我们只要把文件中.bmp之前的内容转化成数字再排个序就好了。代码如下:

#include <algorithm>
#include <vector>

bool SortbyNumASC(const CString& x, const CString& y)
{
    int nLeft, nRight;
    nLeft = atoi(x.Left(x.ReverseFind('.')));
    nRight = atoi(y.Left(y.ReverseFind('.')));
    return nLeft < nRight;
}

// 加入文件到fileList中
CFileFind finder;
std::vector<CString> fileList;

BOOL bHaveFiles = finder.FindFile("*.*");
while (bHaveFiles)
{
    bHaveFiles = finder.FindNextFile();
    fileList.push_back(finder.GetFileName());
}

// 由小到大排
sort(fileList.begin(), fileList.end(), SortbyNumASC);

在我的问题中,文件命名方式如下: CS0001G_A_15.bmp, 因此这里把第二个_后面的字符串中的数字转化为int型数据即可,因此这里对上述代码修改如下:


bool SortbynumASC(const CString& x, const CString& y)
{
    int nLeft = 0;
    int nRight = 0;

    nLeft = atoi(x.Right(x.GetLength()-1 - x.ReverseFind('_')));
    nRight = atoi(y.Right(y.GetLength() - 1 - y.ReverseFind('_')));

    return nLeft < nRight;
}
//其他部分参考上面代码

参考资料

[1.] https://blog.csdn.net/flyfish1986/article/details/5372427
[2.] https://blog.csdn.net/yal179/article/details/32123557

  • 7
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
MFC中,可以使用CFileFind类来实现遍历文件夹中的所有文件的路径。 首先,在需要实现文件夹遍历功能的类中包含头文件<afx.h>和<afx.h>。然后,创建一个CFileFind对象,使用FindFile函数指定初始文件夹路径。接着,使用FindNextFile函数循环遍历文件夹中的文件,直到没有下一个文件为止。在循环中,可以通过GetFilePath函数获取到当前文件的路径,并对其进行相应的处理。 下面是一个简单的示例代码: ```cpp #include <afx.h> #include <afx.h> void TraverseFolder(LPCTSTR szFolderPath) { CFileFind finder; CString strWildcard(szFolderPath); strWildcard += _T("\\*.*"); BOOL bFind = finder.FindFile(strWildcard); while (bFind) { bFind = finder.FindNextFile(); if (finder.IsDirectory() && !finder.IsDots()) // 判断是否是文件夹,但不包括"."和".." { CString strFolder = finder.GetFilePath(); // 处理文件夹路径 TraverseFolder(strFolder); // 递归调用,继续遍历文件夹 } else if (!finder.IsDirectory()) { CString strFile = finder.GetFilePath(); // 处理文件路径 } } finder.Close(); } ``` 在上面的代码中,TraverseFolder函数可以用来遍历指定文件夹及其子文件夹中的所有文件。首先,使用FindFile函数指定初始文件夹路径,并通过FindNextFile函数循环查找下一个文件文件夹。然后,使用IsDirectory函数和IsDots函数判断是否为文件夹,如果是则进行递归调用,继续遍历文件夹。如果不是文件夹,则获取文件路径进行相应处理。 需要注意的是,使用CFileFind类需要在链接器设置中添加MFC库,否则会报链接错误。此外,为了提高程序效率,可以根据实际需求在代码中添加各种过滤条件来筛选文件
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

此人姓于名叫罩百灵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值