c++ - 无法正确递归目录

标签 c++ qt

我正在尝试在我使用 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/

相关文章:

c++ - Qt 自定义委托(delegate)

c++ - 从当前打开 QWidget 或 QWindow

c++ - 用于编译所有文件的 MinGW GCC 通配符 (Windows)

c++ - 如何跟踪拖放操作的生命周期?

c++ - 如何用C语言制作棋盘?

c++ - Qt 中的 QPaintEvent 绘画区域?

qt - pyqt:当小部件变为可见/隐藏时接收信号

没有 .NET 的 C++ 注册表处理

c++ - typeinfo pragma 可见性错误

c++ - 遗产。从父类调用子类函数