In Qt 6.8 QDirListing was added as a more efficient replacement for QDirIterator (the latter is still available for now). This page highlights some points to keep in mind when porting QDirIterator to QDirListing .
采用 QDirIterator you can control which entries are listed using flags from two separate enumerators, QDirIterator::IteratorFlags and QDir::Filters ,而 QDirListing has one set of flags to handle this task.
Porting QDirIterator::IteratorFlags to QDirListing::IteratorFlags is straightforward:
Porting QDir::Filters to QDirListing::IteratorFlags may be more complex, depending on the bitwise OR-ed combination of QDir::Filters you use.
using F = QDirListing::IteratorFlag; QDirListing::IteratorFlags(F::ExcludeOther|F::ResolveSymlinks|F::IncludeDotAndDotDot);
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)) { ... } }
.
and
..
. Set
QDirListing::IteratorFlag::IncludeDotAndDotDot
to list them.
默认情况下, QDirIterator resolves symbolic links unless QDir::NoSymlinks is set, whereas QDirListing doesn't resolve symbolic links unless QDirListing::IteratorFlag::ResolveSymlinks is set, in which case the filtering is done based on the type of the target of the symbolic link, not the symbolic link itself. For example, to list only regular files and symbolic links to regular files, you must set QDirListing::IteratorFlag::FilesOnly and 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
offers a subset of
QFileInfo
's API (for example, fileName(), filePath(), exists()). The main advantage of DirEntry's API is delaying the (rather expensive)
stat()
or
lstat()
calls if we already got the needed info by some other means. On Linux, for example, internally we use readdir() to iterate over a directory tree, and we get the name and type of the entry as part of the returned info. So if all you want is the file name use,
QDirListing::DirEntry::fileName
() 而不是
QDirListing::DirEntry::fileInfo
().fileName() (
QDirListing
will construct a
QFileInfo
internally and use that transparently when needed).