Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qdirlisting-porting.qdoc
Go to the documentation of this file.
1// Copyright (C) 2025 Ahmad Samir <a.samirh78@gmail.com>
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
3
4/*!
5 \page qdiriterator-to-qdirlisting-porting.html
6 \title Porting QDirIterator to QDirListing
7
8 \ingroup how-to
9
10 In Qt 6.8 QDirListing was added as a more efficient replacement for QDirIterator
11 (the latter is still available for now). This page highlights some points to keep
12 in mind when porting QDirIterator to QDirListing.
13
14 With QDirIterator you can control which entries are listed using flags from
15 two separate enumerators, QDirIterator::IteratorFlags and QDir::Filters, whereas
16 QDirListing has one set of flags to handle this task.
17
18 Porting QDirIterator::IteratorFlags to QDirListing::IteratorFlags is straightforward:
19 \list
20 \li QDirListing::IteratorFlag::Default is equivalent to QDirIterator::NoIteratorFlags
21 \li QDirListing::IteratorFlag::FollowDirSymlinks is equivalent to QDirIterator::FollowSymlinks
22 \li QDirListing::IteratorFlag::Recursive is equivalent to QDirIterator::Subdirectories
23 \endlist
24
25 Porting QDir::Filters to QDirListing::IteratorFlags may be more complex, depending
26 on the bitwise OR-ed combination of QDir::Filters you use.
27
28 \list
29 \li By default, QDirListing lists directories, regular files, symbolic links,
30 and special (\e other) file system entries; you can exclude entries based
31 on their type by using the various QDirListing::IteratorFlag::Exclude* flags.
32 \li QDir's default filter is QDir::AllEntries, which is equivalent to:
33 \code
34 using F = QDirListing::IteratorFlag;
35 QDirListing::IteratorFlags(F::ExcludeOther|F::ResolveSymlinks|F::IncludeDotAndDotDot);
36 \endcode
37 \li By default, QDirListing lists (Windows) drives, hence there is no equivalent
38 for QDir::Drives.
39 \li QDir::Readable, QDir::Writable, QDir::Executable, and QDir::AllDirs:
40 The are no equivalent flags in QDirListing. If you need this functionality,
41 iterate over the entries with a range-for loop and filter as required.
42
43 \code
44 QDirIterator dit(dirPath, QDir::AllEntries | QDir::Readable | QDir::Executable | QDir::NoDotAndDotDot);
45 while (dit.hasNext()) {
46 const QFileInfo fi = dit.nextFileInfo();
47 fileNames.append(fi.fileName());
48 ...
49 }
50
51 using F = QDirListing::IteratorFlags;
52 for (const auto &dirEntry : QDirListing(dirPath, F::Default)) {
53 const QFileInfo fi = dirEntry.fileInfo();
54 // Filter based on readable and executable bits
55 if (fi.isReadable() && fi.isExecutable()) {
56 fileNames.append(dirEntry.fileName());
57 ...
58 }
59 }
60 \endcode
61
62 \code
63 // QDir::AllDirs causes dirs to always be listed regardless of `nameFilters`;
64 // for example, to list ".so" files in a file dialog and still list all dirs:
65 QDirIterator dit(dirPath, nameFilters, QDir::AllDirs | QDir::NoDotAndDotDot);
66 while (dit.hasNext()) {
67 const QFileInfo fi = dit.nextFileInfo();
68 ...
69 }
70
71 // Equivalent code using QDirListing:
72 using F = QDirListing::IteratorFlags;
73 for (const auto &dirEntry : QDirListing(dirPath, F::Default)) {
74 const QFileInfo fi = dirEntry.fileInfo();
75 if (fi.isDir() || fi.fileName().endsWith(".so"_L1)) {
76 ...
77 }
78 }
79 \endcode
80 \li With QDirListing the semantics of QDir::NoDot, QDir::NoDotDot and
81 QDir::NoDotAndDotDot have been combined into one flag. By default,
82 QDirListing doesn't list the special entries \c {.} and \c {..}.
83 Set QDirListing::IteratorFlag::IncludeDotAndDotDot to list them.
84 \endlist
85
86 \section1 Symbolic Links
87 By default, QDirIterator resolves symbolic links unless QDir::NoSymlinks is set,
88 whereas QDirListing doesn't resolve symbolic links unless
89 QDirListing::IteratorFlag::ResolveSymlinks is set, in which case the filtering
90 is done based on the type of the target of the symbolic link, not the symbolic
91 link itself. For example, to list only regular files \e and symbolic links to
92 regular files, you must set QDirListing::IteratorFlag::FilesOnly \e and
93 QDirListing::IteratorFlag::ResolveSymlinks.
94
95 \code
96 // Symbolic links are resolved by default
97 QDirIterator dit(dirPath, QDir::Files | QDir::NoDotAndDotDot);
98 while (dit.hasNext()) {
99 const QFileInfo fi = dit.nextFileInfo();
100 fileNames.append(fi.fileName());
101 ...
102 }
103
104 // To preserve the behavior of the code above, set ResolveSymlinks:
105 using F = QDirListing::IteratorFlags;
106 for (const auto &dirEntry : QDirListing(dirPath, F::FilesOnly | F::ResolveSymlinks)) {
107 fileNames.append(dirEntry.fileName());
108 ...
109 }
110 \endcode
111
112 \section1 QDirListing::DirEntry
113 QDirListing::DirEntry offers a subset of QFileInfo's API (for example, fileName(),
114 filePath(), exists()). The main advantage of DirEntry's API is delaying the (rather
115 expensive) \c stat() or \c lstat() calls if we already got the needed info by some
116 other means. On Linux, for example, internally we use readdir() to iterate over a
117 directory tree, and we get the name and type of the entry as part of the returned
118 info. So if all you want is the file name use, QDirListing::DirEntry::fileName()
119 instead of QDirListing::DirEntry::fileInfo().fileName() (QDirListing will construct
120 a QFileInfo internally and use that transparently when needed).
121*/