我正在尝试在我使用 QT Creator 应用程序创建的 C++ 程序中递归目录。出于某种原因,QDir::entryList 和 QDirIterator 似乎都不起作用。使用 QDirIterator 我可以获取第二个目录,但它不会继续。当我将 QDir::entryList 与嵌套的 foreach 循环一起使用时,会发生类似的事情。最终,我想获取目录链中不包含其他目录的最后一个目录。
这是为了跨平台,所以它不能特定于操作系统。我还想避免针对不同操作系统的大量开关,因为我不想以后再处理它而只是使用它(可能永远)。我已经尝试过 foreach 循环、while 循环以及我能想到的任何东西。
QDir 代码:
QStringList GetLastSubDirs(QDir baseDirectory) {
QStringList result;
baseDirectory.setFilter( QDir::Dirs|QDir::NoDotAndDotDot );
QStringList nonEmptyDirs(baseDirectory.path());
while (nonEmptyDirs.size() > 0) {
foreach (QString d, nonEmptyDirs) {
QDir sd(d);
foreach (QDir checkingDir, sd.entryList(QDir::Dirs|QDir::NoDotAndDotDot)) {
if (checkingDir.entryList().size() == 0) {
result.append(checkingDir.path());
} else {
nonEmptyDirs.append(checkingDir.path());
}
}
nonEmptyDirs.removeOne(d);
}
}
if (result.size() == 0) {
result = QStringList(baseDirectory.path());
}
return result;
}
};
这是 QDirIterator 代码:
class Directories
{
public:
QStringList GetLastSubDirs(QDir baseDirectory) {
QStringList result;
baseDirectory.setFilter( QDir::Dirs|QDir::NoDotAndDotDot );
QDirIterator it(QDir::currentPath() + "/" + baseDirectory.path(), QDirIterator::Subdirectories);
while(it.hasNext()) {
QDir curWorkDir(it.path());
curWorkDir.setFilter( QDir::Dirs|QDir::NoDot|QDir::NoDotDot );
if(curWorkDir.entryList().size() >= 1) {
foreach (QDir d, curWorkDir.entryList()) {
d.setFilter( QDir::Dirs|QDir::NoDot|QDir::NoDotDot );
if (d.entryList().size() <= 0) {
result.append(d.path());
}
}
} else {
result.append(curWorkDir.path());
}
it.next();
}
if (result.size() == 0) {
result = QStringList(baseDirectory.path());
}
return result;
}
};
调试器输出
1 Directories::GetLastSubDirs main.cpp 56 0x555555559ba9
2 Games::Games main.cpp 80 0x555555559f98
3 __static_initialization_and_destruction_0 main.cpp 104 0x55555555931b
4 _GLOBAL__sub_I_main.cpp(void) main.cpp 120 0x55555555934e
5 __libc_csu_init 0x55555555cd9d
6 __libc_start_main libc-start.c 247 0x7ffff54ed270
7 _start 0x555555558f2a
反汇编输出:
0x555555558f00 31 ed xor %ebp,%ebp
0x555555558f02 <+ 2> 49 89 d1 mov %rdx,%r9
0x555555558f05 <+ 5> 5e pop %rsi
0x555555558f06 <+ 6> 48 89 e2 mov %rsp,%rdx
0x555555558f09 <+ 9> 48 83 e4 f0 and $0xfffffffffffffff0,%rsp
0x555555558f0d <+ 13> 50 push %rax
0x555555558f0e <+ 14> 54 push %rsp
0x555555558f0f <+ 15> 4c 8d 05 aa 3e 00 00 lea 0x3eaa(%rip),%r8 # 0x55555555cdc0 <__libc_csu_fini>
0x555555558f16 <+ 22> 48 8d 0d 33 3e 00 00 lea 0x3e33(%rip),%rcx # 0x55555555cd50 <__libc_csu_init>
0x555555558f1d <+ 29> 48 8d 3d 74 01 00 00 lea 0x174(%rip),%rdi # 0x555555559098 <main(int, char**)>
0x555555558f24 <+ 36> ff 15 c6 70 20 00 callq *0x2070c6(%rip) # 0x55555575fff0
0x555555558f2a <+ 42> f4 hlt
我希望这个特定的代码片段递归目录,直到它清除了包含其他目录的任何目录。相反,它只会下降一级并停止。出于某种原因,在查询这些目录的 entryList().size() 时,它总是返回 0,即使该目录包含其他目录,除非我包含 .
和 ..
然后它就一直循环下去,因为它并不是为了处理这个问题。
最佳答案
我不知道你为什么把它搞得这么复杂。 documentation是这样说的:
QDirIterator 类为目录条目列表提供迭代器。
您可以使用 QDirIterator 一次导航一个目录条目。它类似于 QDir::entryList() 和 QDir::entryInfoList(),但是因为它一次列出一个条目而不是一次列出所有条目,所以它的扩展性更好并且更适合大型目录。它还支持递归列出目录内容,并支持符号链接(symbolic link)。与 QDir::entryList() 不同,QDirIterator 不支持排序。
QDirIterator 构造函数将 QDir 或目录作为参数。构造后,迭代器位于第一个目录条目之前。以下是按顺序遍历所有条目的方法:
QDirIterator it("/etc", QDirIterator::Subdirectories);
while (it.hasNext()) {
qDebug() << it.next();
// /etc/.
// /etc/..
// /etc/X11
// /etc/X11/fs
// ...
}
QDirIterator 在提供 QDirIterator::Subdirectories 时已经是递归的。
关于c++ - 无法正确递归目录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56591807/