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
网友评论