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
qdiriterator.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
5/*!
6 \since 4.3
7 \class QDirIterator
8 \inmodule QtCore
9 \ingroup io
10 \brief The QDirIterator class provides an iterator for directory entrylists.
11
12 You can use QDirIterator to navigate entries of a directory one at a time.
13 It is similar to QDir::entryList() and QDir::entryInfoList(), but because
14 it lists entries one at a time instead of all at once, it scales better
15 and is more suitable for large directories. It also supports listing
16 directory contents recursively, and following symbolic links. Unlike
17 QDir::entryList(), QDirIterator does not support sorting.
18
19 The QDirIterator constructor takes a QDir or a directory as
20 argument. After construction, the iterator is located before the first
21 directory entry. Here's how to iterate over all the entries sequentially:
22
23 \snippet code/src_corelib_io_qdiriterator.cpp 0
24
25 Here's how to find and read all files filtered by name, recursively:
26
27 \snippet code/src_corelib_io_qdiriterator.cpp 1
28
29 The next() and nextFileInfo() functions advance the iterator and return
30 the path or the QFileInfo of the next directory entry. You can also call
31 filePath() or fileInfo() to get the current file path or QFileInfo without
32 first advancing the iterator. The fileName() function returns only the
33 name of the file, similar to how QDir::entryList() works.
34
35 Unlike Qt's container iterators, QDirIterator is uni-directional (i.e.,
36 you cannot iterate directories in reverse order) and does not allow random
37 access.
38
39 \note This class is deprecated and may be removed in a Qt release. Use
40 QDirListing instead, see \l {Porting QDirIterator to QDirListing}.
41
42 \sa QDir, QDir::entryList()
43*/
44
45/*! \enum QDirIterator::IteratorFlag
46
47 This enum describes flags that you can combine to configure the behavior
48 of QDirIterator.
49
50 \value NoIteratorFlags The default value, representing no flags. The
51 iterator will return entries for the assigned path.
52
53 \value Subdirectories List entries inside all subdirectories as well.
54
55 \value FollowSymlinks When combined with Subdirectories, this flag
56 enables iterating through all subdirectories of the assigned path,
57 following all symbolic links. Symbolic link loops (e.g., "link" => "." or
58 "link" => "..") are automatically detected and ignored.
59*/
60
61#include "qdiriterator.h"
62#include "qdir_p.h"
64#include "qdirlisting.h"
66
67#include <QtCore/qset.h>
68#include <QtCore/qstack.h>
69#include <QtCore/qvariant.h>
70#if QT_CONFIG(regularexpression)
71#include <QtCore/qregularexpression.h>
72#endif
73
74#include <QtCore/private/qfilesystemiterator_p.h>
75#include <QtCore/private/qfilesystementry_p.h>
76#include <QtCore/private/qfilesystemmetadata_p.h>
77#include <QtCore/private/qfilesystemengine_p.h>
78#include <QtCore/private/qfileinfo_p.h>
79#include <QtCore/private/qduplicatetracker_p.h>
80
81#include <memory>
82#include <stack>
83#include <vector>
84
85QT_BEGIN_NAMESPACE
86
87using namespace Qt::StringLiterals;
88
89static QDirListing::IteratorFlags toDirListingFlags(QDir::Filters filters,
90 QDirIterator::IteratorFlags flags)
91{
92 using F = QDirListing::IteratorFlag;
93 QDirListing::IteratorFlags listerFlags = QDirPrivate::toDirListingFlags(filters);
94
95 if (flags & QDirIterator::FollowSymlinks)
96 listerFlags |= F::FollowDirSymlinks;
97 if (flags & QDirIterator::Subdirectories)
98 listerFlags |= F::Recursive;
99 return listerFlags;
100}
101
103{
104public:
105 QDirIteratorPrivate(const QString &path, const QStringList &nameFilters = {},
106 QDir::Filters dirFilters = QDir::NoFilter,
107 QDirIterator::IteratorFlags flags = QDirIterator::NoIteratorFlags)
110 {
111 it = lister.begin();
112 skipToNextMatch(it);
113 }
114
116 {
117 while (iter != lister.end()) {
118 const QDirListing::DirEntry &dirEntry = *iter;
119 if (QDirPrivate::checkNonDirListingFlags(dirEntry, filters)) {
120 nextFileInfo = dirEntry.fileInfo();
121 break;
122 }
123 ++iter;
124 }
125 }
126
127 void advance()
128 {
129 // Match the behavior of advance() from before porting to QDirListing,
130 // that is, even if hasNext() returns false, calling next() returns an
131 // empty string without crashing. QTBUG-130142
132 if (it == lister.end()) {
133 currentFileInfo = {};
134 return;
135 }
136 currentFileInfo = nextFileInfo;
137 skipToNextMatch(++it);
138 }
139
143 QFileInfo nextFileInfo;
145};
146
147/*!
148 Constructs a QDirIterator that can iterate over \a dir's entrylist, using
149 \a dir's name filters and regular filters. You can pass options via \a
150 flags to decide how the directory should be iterated.
151
152 By default, \a flags is NoIteratorFlags, which provides the same behavior
153 as in QDir::entryList().
154
155 The sorting in \a dir is ignored.
156
157 \note To list symlinks that point to non existing files, QDir::System must be
158 passed to the flags.
159
160 \sa hasNext(), next(), IteratorFlags
161*/
162QDirIterator::QDirIterator(const QDir &dir, IteratorFlags flags)
163 : d(new QDirIteratorPrivate(dir.path(), dir.nameFilters(), dir.filter(), flags))
164{
165}
166
167/*!
168 Constructs a QDirIterator that can iterate over \a path, with no name
169 filtering and \a filters for entry filtering. You can pass options via \a
170 flags to decide how the directory should be iterated.
171
172 By default, \a filters is QDir::NoFilter, and \a flags is NoIteratorFlags,
173 which provides the same behavior as in QDir::entryList().
174
175 \note To list symlinks that point to non existing files, QDir::System must be
176 passed to the flags.
177
178 \sa hasNext(), next(), IteratorFlags
179*/
180QDirIterator::QDirIterator(const QString &path, QDir::Filters filters, IteratorFlags flags)
181 : d(new QDirIteratorPrivate(path, {}, filters, flags))
182{
183}
184
185/*!
186 Constructs a QDirIterator that can iterate over \a path. You can pass
187 options via \a flags to decide how the directory should be iterated.
188
189 By default, \a flags is NoIteratorFlags, which provides the same behavior
190 as in QDir::entryList().
191
192 \note To list symlinks that point to non existing files, QDir::System must be
193 passed to the flags.
194
195 \sa hasNext(), next(), IteratorFlags
196*/
197QDirIterator::QDirIterator(const QString &path, IteratorFlags flags)
198 : d(new QDirIteratorPrivate(path, {}, QDir::NoFilter, flags))
199{
200}
201
202/*!
203 Constructs a QDirIterator that can iterate over \a path, using \a
204 nameFilters and \a filters. You can pass options via \a flags to decide
205 how the directory should be iterated.
206
207 By default, \a flags is NoIteratorFlags, which provides the same behavior
208 as QDir::entryList().
209
210 For example, the following iterator could be used to iterate over audio
211 files:
212
213 \snippet code/src_corelib_io_qdiriterator.cpp 2
214
215 \note To list symlinks that point to non existing files, QDir::System must be
216 passed to the flags.
217
218 \sa hasNext(), next(), IteratorFlags, QDir::setNameFilters()
219*/
220QDirIterator::QDirIterator(const QString &path, const QStringList &nameFilters,
221 QDir::Filters filters, IteratorFlags flags)
222 : d(new QDirIteratorPrivate(path, nameFilters, filters, flags))
223{
224}
225
226/*!
227 Destroys the QDirIterator.
228*/
229QDirIterator::~QDirIterator()
230{
231}
232
233/*!
234 Advances the iterator to the next entry, and returns the file path of this
235 new entry. If hasNext() returns \c false, this function does nothing, and
236 returns an empty QString. Ideally you should always call hasNext() before
237 calling this method.
238
239 You can call fileName() or filePath() to get the current entry's file name
240 or path, or fileInfo() to get a QFileInfo for the current entry.
241
242 Call nextFileInfo() instead of next() if you're interested in the QFileInfo.
243
244 \sa hasNext(), nextFileInfo(), fileName(), filePath(), fileInfo()
245*/
246QString QDirIterator::next()
247{
248 d->advance();
249 return d->currentFileInfo.filePath();
250}
251
252/*!
253 \since 6.3
254
255 Advances the iterator to the next entry, and returns the file info of this
256 new entry. If hasNext() returns \c false, this function does nothing, and
257 returns an empty QFileInfo. Ideally you should always call hasNext() before
258 calling this method.
259
260 You can call fileName() or filePath() to get the current entry's file name
261 or path, or fileInfo() to get a QFileInfo for the current entry.
262
263 Call next() instead of nextFileInfo() when all you need is the filePath().
264
265 \sa hasNext(), fileName(), filePath(), fileInfo()
266*/
267QFileInfo QDirIterator::nextFileInfo()
268{
269 d->advance();
270 return d->currentFileInfo;
271}
272
273/*!
274 Returns \c true if there is at least one more entry in the directory;
275 otherwise, false is returned.
276
277 \sa next(), nextFileInfo(), fileName(), filePath(), fileInfo()
278*/
279bool QDirIterator::hasNext() const
280{
281 return d->it != d->lister.end();
282}
283
284/*!
285 Returns the file name for the current directory entry, without the path
286 prepended.
287
288 This function is convenient when iterating a single directory. When using
289 the QDirIterator::Subdirectories flag, you can use filePath() to get the
290 full path.
291
292 \sa filePath(), fileInfo()
293*/
294QString QDirIterator::fileName() const
295{
296 return d->currentFileInfo.fileName();
297}
298
299/*!
300 Returns the full file path for the current directory entry.
301
302 \sa fileInfo(), fileName()
303*/
304QString QDirIterator::filePath() const
305{
306 return d->currentFileInfo.filePath();
307}
308
309/*!
310 Returns a QFileInfo for the current directory entry.
311
312 \sa filePath(), fileName()
313*/
314QFileInfo QDirIterator::fileInfo() const
315{
316 return d->currentFileInfo;
317}
318
319/*!
320 Returns the base directory of the iterator.
321*/
322QString QDirIterator::path() const
323{
324 return d->lister.iteratorPath();
325}
326
327QT_END_NAMESPACE
QDirIteratorPrivate(const QString &path, const QStringList &nameFilters={}, QDir::Filters dirFilters=QDir::NoFilter, QDirIterator::IteratorFlags flags=QDirIterator::NoIteratorFlags)
QDir::Filters filters
void skipToNextMatch(QDirListing::const_iterator &iter)
QDirListing::const_iterator it
\inmodule QtCore
Definition qdirlisting.h:68
reference operator*() const
Returns a {const QDirListing::DirEntry &} of the directory entry this iterator points to.
const_iterator & operator++()
Pre-increment operator.
IteratorFlag
This enum class describes flags that can be used to configure the behavior of QDirListing.
Definition qdirlisting.h:29
static QDirListing::IteratorFlags toDirListingFlags(QDir::Filters filters, QDirIterator::IteratorFlags flags)