本页内容

将 QDirIterator 移植到 QDirListing

在 Qt 6.8 中,新增了QDirListing 作为QDirIterator 的更高效替代方案(后者目前仍可用)。本页面重点介绍了将QDirIterator 移植到QDirListing 时需要注意的几点事项。

使用QDirIterator 时,您可以通过两个独立枚举器(QDirIterator::IteratorFlags 和QDir::Filters )的标志来控制要列出的条目;而QDirListing 仅使用一组标志来处理此任务。

将QDirIterator::IteratorFlags 移植到QDirListing::IteratorFlags 非常简单:

将QDir::Filters 移植到QDirListing::IteratorFlags 可能会更复杂,这取决于您使用的QDir::Filters 的按位或(OR)组合。

  • 默认情况下,QDirListing 会列出目录、普通文件、符号链接以及特殊(其他)文件系统条目;您可以通过使用各种 QDirListing::IteratorFlag::Exclude* 标志,根据条目类型将其排除。
  • QDir的默认过滤器是 `QDir::AllEntries`,这等同于:
    using F = QDirListing::IteratorFlag;
    QDirListing::IteratorFlags(F::ExcludeOther|F::ResolveSymlinks|F::IncludeDotAndDotDot);
  • 默认情况下,QDirListing 会列出(Windows)驱动器,因此QDir::Drives 没有等效选项。
  • QDir::Readable、QDir::Writable 、QDir::Executable 以及QDir::AllDirs :QDirListing 中没有相应的标志。如果您需要此功能,请使用 range-for 循环遍历条目,并按需进行过滤。
    QDirIterator dit(dirPath, QDir::AllEntries | QDir::Readable | QDir::Executable | QDir::NoDotAndDotDot);
    while (dit.hasNext()) {
        const QFileInfo fi = dit.nextFileInfo();
        fileNames.append(fi.fileName());
        ...
    }
    
    using F = QDirListing::IteratorFlags;
    for (const auto &dirEntry : QDirListing(dirPath, F::Default)) {
        const QFileInfo fi = dirEntry.fileInfo();
        // Filter based on readable and executable bits
        if (fi.isReadable() && fi.isExecutable()) {
            fileNames.append(dirEntry.fileName());
            ...
        }
    }
    // QDir::AllDirs causes dirs to always be listed regardless of `nameFilters`;
    // for example, to list ".so" files in a file dialog and still list all dirs:
    QDirIterator dit(dirPath, nameFilters, QDir::AllDirs | QDir::NoDotAndDotDot);
    while (dit.hasNext()) {
        const QFileInfo fi = dit.nextFileInfo();
        ...
    }
    
    // Equivalent code using QDirListing:
    using F = QDirListing::IteratorFlags;
    for (const auto &dirEntry : QDirListing(dirPath, F::Default)) {
        const QFileInfo fi = dirEntry.fileInfo();
        if (fi.isDir() || fi.fileName().endsWith(".so"_L1)) {
            ...
        }
    }
  • 在QDirListing 中,QDir::NoDot 、QDir::NoDotDot 和QDir::NoDotAndDotDot 的功能已被合并为一个标志。默认情况下,QDirListing 不会列出特殊条目. 和.. 。请设置QDirListing::IteratorFlag::IncludeDotAndDotDot 以列出这些条目。

默认情况下,QDirIterator 会解析符号链接,除非设置了QDir::NoSymlinks;而QDirListing 则不会解析符号链接,除非设置了QDirListing::IteratorFlag::ResolveSymlinks ——此时过滤是基于符号链接目标的类型进行的,而非符号链接本身。例如,若要仅列出普通文件以及指向普通文件的符号链接,必须同时设置QDirListing::IteratorFlag::FilesOnly 和 QDirListing::IteratorFlag::ResolveSymlinks 。

// Symbolic links are resolved by default
QDirIterator dit(dirPath, QDir::Files | QDir::NoDotAndDotDot);
while (dit.hasNext()) {
    const QFileInfo fi = dit.nextFileInfo();
    fileNames.append(fi.fileName());
    ...
}

// To preserve the behavior of the code above, set ResolveSymlinks:
using F = QDirListing::IteratorFlags;
for (const auto &dirEntry : QDirListing(dirPath, F::FilesOnly | F::ResolveSymlinks)) {
    fileNames.append(dirEntry.fileName());
    ...
}

QDirListing::DirEntry

QDirListing::DirEntry 提供了QFileInfo API的一部分功能(例如 fileName()、filePath()、exists())。DirEntry API的主要优势在于,如果我们已经通过其他方式获取了所需信息,则会延迟调用(相当耗时的)stat() 或lstat() 。 例如在 Linux 上,我们内部使用 readdir() 遍历目录树,并从返回的信息中获取条目的名称和类型。因此,如果您只需要文件名,请使用QDirListing::DirEntry::fileName() 代替QDirListing::DirEntry::fileInfo().fileName()(QDirListing 会在内部构建一个QFileInfo ,并在需要时透明地使用它)。

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.