【发布时间】:2018-03-03 00:47:00
【问题描述】:
使用 MFC,我递归地遍历文件夹结构以获取文件列表。这很好用,但是在处理文件时,我想先处理一个文件夹中的所有文件,然后再进入子文件夹。例如,如果我有以下层次结构:
\A.txt
\B.txt
\C\C1.txt
\C\C2.txt
\D.txt
\E.txt
\F\F1.txt
\F\F2.txt
\F\F3\F4.txt
\F\F3\F5.txt
\F\F6.txt
\G.txt
\H.txt
\I.txt
...
我想在进入 \C 之前处理 \ 中的所有文件(A.txt、B.txt、D.txt、E.txt 等),并在进入 \F\F3 之前处理 \F 中的所有文件.但是当我将这些文件收集到一个 std::vector 中时,向量的填充与上面的列表完全相同。我怀疑这是因为 Windows 操作系统的一些内部排序。然后,当我遍历向量并在“路径”部分发生更改时输出一条消息时,我得到类似于以下内容:
Processing files in \
Processing files in \C
Processing files in \
Processing files in \F
Processing files in \F\F3
Processing files in \F
Processing files in \
当我更喜欢这样的东西时,这看起来好像处理在文件夹之间来回跳转:
Processing files in \
Processing files in \C
Processing files in \F
Processing files in \F\F3
...
并在移动到同级文件夹之前处理完整层次结构的所有文件。本质上,消息应根据所使用的文件夹结构按字母顺序显示。
我曾想过使用 CFileFind::IsDirectory 来保存文件夹列表,直到整个文件夹都被遍历,然后进入每个保存的文件夹名称列表并遍历它(并在继续之前保存自己的文件夹列表等.),但这似乎有点矫枉过正。一定有更好的方法。
我当前的代码类似于以下,其中 iFound 是完整层次结构中所有文件的计数:
void GetFiles(CString& strSrcFolder, int& iFound)
{
CString strFileSpec(strSrcFolder);
if (strFileSpec.Right(1) != _T("\\"))
strFileSpec += "\\";
strFileSpec += _T("*.*");
CFileFind Search;
BOOL bFound = Search.FindFile(strFileSpec);
while (bFound) {
bFound = Search.FindNextFile();
if (Search.IsDots())
continue;
if (Search.IsDirectory()) {
if (m_oPrefs.Recurse())
GetFiles(Search.GetFilePath(), iFound);
else
continue;
}
else {
m_vFiles.push_back(Search.GetFilePath());
++iFound;
}
}
Search.Close();
}
我希望我已经使我想要完成的事情易于理解,但不要犹豫,询问是否需要进一步澄清。 TIA。
【问题讨论】:
-
因为您需要按字母排序,所以无论如何都必须存储目录项(
CFileFind或底层FindFirstFile、FindNextFileAPI 无法保证您的字母顺序),因此无需担心“矫枉过正”。 -
不要处理文件和目录,而是这样处理:如果是文件处理它,如果是目录,则将其放入列表中。遍历当前级别的所有文件和目录后,处理列表中的目录。就是这样。