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.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// Copyright (C) 2024 Ahmad Samir <a.samirh78@gmail.com>
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4// Qt-Security score:significant reason:default
5
6/*!
7 \since 6.8
8 \class QDirListing
9 \inmodule QtCore
10 \ingroup io
11 \brief The QDirListing class provides an STL-style iterator for directory entries.
12
13 You can use QDirListing to navigate entries of a directory one at a time.
14 It is similar to QDir::entryList() and QDir::entryInfoList(), but because
15 it lists entries one at a time instead of all at once, it scales better
16 and is more suitable for large directories. It also supports listing
17 directory contents recursively, and following symbolic links. Unlike
18 QDir::entryList(), QDirListing does not support sorting.
19
20 The QDirListing constructor takes a directory path string as
21 argument. Here's how to iterate over all entries recursively:
22
23 \snippet code/src_corelib_io_qdirlisting.cpp 0
24
25 Here's how to find and read all regular files filtered by name, recursively:
26
27 \snippet code/src_corelib_io_qdirlisting.cpp 1
28
29 Here's how to list only regular files, recursively:
30 \snippet code/src_corelib_io_qdirlisting.cpp 5
31
32 Here's how to list only regular files and symbolic links to regular
33 files, recursively:
34 \snippet code/src_corelib_io_qdirlisting.cpp 6
35
36//! [std-input-iterator-tag]
37 QDirListing::const_iterator models C++20
38 \l{https://en.cppreference.com/w/cpp/iterator/input_iterator}{std::input_iterator},
39 that is, it is a move-only, forward-only, single-pass iterator, that
40 doesn't allow random access.
41//! [std-input-iterator-tag]
42 It can be used in ranged-for loops (or with C++20 range algorithms that don't
43 require random access iterators). Dereferencing a valid iterator returns
44 a QDirListing::DirEntry object. The (c)end() sentinel marks the end of
45 the iteration. Dereferencing an iterator that is equal to \l{sentinel} is
46 undefined behavior.
47
48 QDirListing::DirEntry offers a subset of QFileInfo's API (for example,
49 fileName(), filePath(), exists()). Internally, DirEntry only constructs
50 a QFileInfo object if needed, that is, if the info hasn't been already
51 fetched by other system functions. You can use DirEntry::fileInfo()
52 to get a QFileInfo. For example:
53
54 \snippet code/src_corelib_io_qdirlisting.cpp 3
55 \snippet code/src_corelib_io_qdirlisting.cpp 4
56
57 \sa QDir, QDir::entryList()
58*/
59
60/*! \enum QDirListing::IteratorFlag
61
62 This enum class describes flags that can be used to configure the behavior
63 of QDirListing. Values from this enumerator can be bitwise OR'ed together.
64
65 \value Default
66 List all entries, that is, files, directories, symbolic links including broken
67 symbolic links (where the target doesn't exist) and special (\e other) system
68 files, see ExcludeOther for details.
69 Hidden files and directories and the special entries \c{.} and \c{..}
70 aren't listed by default.
71
72 \value ExcludeFiles
73 Don't list regular files. When combined with ResolveSymlinks, symbolic
74 links to regular files will be excluded too.
75
76 \value ExcludeDirs
77 Don't list directories. When combined with ResolveSymlinks, symbolic
78 links to directories will be excluded too.
79
80 \omitvalue ExcludeSpecial
81 \value ExcludeOther [since 6.10]
82 Don't list file system entries that are \e not directories, regular files,
83 or symbolic links.
84 \list
85 \li On Unix, a special (other) file system entry is a FIFO, socket,
86 character device, or block device. For more details see the
87 \l{https://pubs.opengroup.org/onlinepubs/9699919799/functions/mknod.html}{\c mknod}
88 manual page.
89 \li On Windows (for historical reasons) \c .lnk files are considered
90 special (other) file system entries.
91 \endlist
92
93 \value ResolveSymlinks
94 Filter symbolic links based on the type of the target of the link,
95 rather than the symbolic link itself. Broken symbolic links (where
96 the target doesn't exist) are excluded, set IncludeBrokenSymlinks
97 to include them.
98 This flag is ignored on operating systems that don't support symbolic links.
99
100 \value IncludeBrokenSymlinks [since 6.11]
101 Lists broken symbolic links, where the target doesn't exist, regardless
102 of the status of the ResolveSymlinks flag.
103 This flag is ignored on operating systems that don't support symbolic links.
104
105 \value FilesOnly
106 Only regular files will be listed. When combined with ResolveSymlinks,
107 symbolic links to files will also be listed.
108
109 \value DirsOnly
110 Only directories will be listed. When combined with ResolveSymlinks,
111 symbolic links to directories will also be listed.
112
113 \value IncludeHidden
114 List hidden entries. When combined with Recursive, the iteration will
115 recurse into hidden sub-directories as well.
116
117 \value IncludeDotAndDotDot
118 List the \c {.} and \c{..} special entries.
119
120 \value CaseSensitive
121 The file glob patterns in the name filters passed to the QDirListing
122 constructor, will be matched case sensitively (for details, see
123 QDir::setNameFilters()).
124
125 \value Recursive
126 List entries inside all sub-directories as well. When combined with
127 FollowDirSymlinks, symbolic links to directories will be iterated too.
128
129 \value FollowDirSymlinks
130 When combined with Recursive, symbolic links to directories will be
131 iterated too. Symbolic link loops (e.g., link => . or link => ..) are
132 automatically detected and ignored.
133
134 \omitvalue NoNameFiltersForDirs
135*/
136
137#include "qdirlisting.h"
138#include "qdirentryinfo_p.h"
139
140#include "qdir_p.h"
141#include "qdiriterator.h"
143
144#if QT_CONFIG(regularexpression)
145#include <QtCore/qregularexpression.h>
146#endif
147
148#include <QtCore/private/qfilesystemiterator_p.h>
149#include <QtCore/private/qfilesystementry_p.h>
150#include <QtCore/private/qfilesystemmetadata_p.h>
151#include <QtCore/private/qfilesystemengine_p.h>
152#include <QtCore/private/qfileinfo_p.h>
153#include <QtCore/private/qduplicatetracker_p.h>
154
155#include <memory>
156#include <stack>
157#include <vector>
158
159QT_BEGIN_NAMESPACE
160
161using namespace Qt::StringLiterals;
162
164{
166public:
168
169 // the default for std::stack is std::deque, but std::vector is more apt:
170 template <typename T>
172 {
173 using Base = std::stack<T, std::vector<T>>;
174 using Base::Base;
175 void clear() { this->c.clear(); } // std::stack is also missing clear()
176 };
177
178 void init();
179 void advance();
181
182 bool entryMatches(QDirEntryInfo &info);
183 void pushDirectory(QDirEntryInfo &info);
185
186 void checkAndPushDirectory(QDirEntryInfo &info);
187 bool matchesFilters(QDirEntryInfo &data) const;
188 bool hasIterators() const;
189
195
196#if QT_CONFIG(regularexpression)
198 bool regexMatchesName(const QString &fileName) const
199 {
200 if (nameRegExps.empty())
201 return true;
202 auto hasMatch = [&fileName](const auto &re) { return re.match(fileName).hasMatch(); };
204 }
205#endif
206
209#ifndef QT_NO_FILESYSTEMITERATOR
212#endif
213
214 // Loop protection
216};
217
219{
220 if (nameFilters.contains("*"_L1))
221 nameFilters.clear();
222
223#if QT_CONFIG(regularexpression)
224 nameRegExps.reserve(size_t(nameFilters.size()));
225
226 const bool isCase = iteratorFlags.testAnyFlags(QDirListing::IteratorFlag::CaseSensitive);
227 const auto cs = isCase ? Qt::CaseSensitive : Qt::CaseInsensitive;
228 for (const auto &filter : std::as_const(nameFilters))
229 nameRegExps.emplace_back(QRegularExpression::fromWildcard(filter, cs));
230#endif
231
232 engine = QFileSystemEngine::createLegacyEngine(initialEntryInfo.entry,
233 initialEntryInfo.metaData);
234}
235
236/*!
237 \internal
238
239 Resets the iteration state (if any), so that calling begin()/cbegin()
240 always starts iterating anew.
241*/
243{
244#ifndef QT_NO_FILESYSTEMITERATOR
245 nativeIterators.clear();
246#endif
247 fileEngineIterators.clear();
248 visitedLinks.clear();
249 pushDirectory(initialEntryInfo);
250}
251
252void QDirListingPrivate::pushDirectory(QDirEntryInfo &entryInfo)
253{
254 const QString path = [&entryInfo] {
255#ifdef Q_OS_WIN
256 if (entryInfo.isSymLink())
257 return entryInfo.canonicalFilePath();
258#endif
259 return entryInfo.filePath();
260 }();
261
262
263 if (iteratorFlags.testAnyFlags(QDirListing::IteratorFlag::FollowDirSymlinks)) {
264 // Stop link loops
265 if (visitedLinks.hasSeen(entryInfo.canonicalFilePath()))
266 return;
267 }
268
269 if (engine) {
270 engine->setFileName(path);
271 if (auto it = engine->beginEntryList(path, iteratorFlags, nameFilters)) {
272 fileEngineIterators.push(std::move(it));
273 } else {
274 // No iterator; no entry list.
275 }
276 } else {
277#ifndef QT_NO_FILESYSTEMITERATOR
278 QFileSystemEntry *fentry = nullptr;
279 if (entryInfo.fileInfoOpt)
280 fentry = &entryInfo.fileInfoOpt->d_ptr->fileEntry;
281 else
282 fentry = &entryInfo.entry;
283 nativeIterators.push(std::make_unique<QFileSystemIterator>(*fentry, iteratorFlags));
284#else
285 qWarning("Qt was built with -no-feature-filesystemiterator: no files/plugins will be found!");
286#endif
287 }
288}
289
290bool QDirListingPrivate::entryMatches(QDirEntryInfo &entryInfo)
291{
292 checkAndPushDirectory(entryInfo);
293 return matchesFilters(entryInfo);
294}
295
296/*!
297 \internal
298
299 Advances the internal iterator, either a QAbstractFileEngineIterator (e.g.
300 QResourceFileEngineIterator) or a QFileSystemIterator (which uses low-level
301 system methods, e.g. readdir() on Unix). The iterators are stored in a
302 stack.
303
304 A typical example of doing recursive iteration:
305 - while iterating directory A we find a sub-dir B
306 - an iterator for B is pushed to the stack
307 - B's iterator is processed (stack.top()) first; then the loop
308 goes back to processing A's iterator
309*/
311{
312 if (engine) {
313 while (!fileEngineIterators.empty()) {
314 // Find the next valid iterator that matches the filters.
315 // Always use top() because entryMatches() may modify `fileEngineIterators`!
316 while (fileEngineIterators.top()->advance()) {
317 QDirEntryInfo entryInfo{fileEngineIterators.top()->currentFileInfo()};
318 if (entryMatches(entryInfo)) {
319 currentEntryInfo = std::move(entryInfo);
320 return;
321 }
322 }
323
324 fileEngineIterators.pop();
325 }
326 } else {
327#ifndef QT_NO_FILESYSTEMITERATOR
328 while (!nativeIterators.empty()) {
329 // Find the next valid iterator that matches the filters.
330 // Always use top() because entryMatches() may modify `nativeIterators`!
331 while (std::optional r = nativeIterators.top()->advance()) {
332 if (entryMatches(*r)) {
333 currentEntryInfo = std::move(*r);
334 return;
335 }
336 }
337
338 nativeIterators.pop();
339 }
340#endif
341 }
342}
343
344static bool isDotOrDotDot(QStringView fileName)
345{
346 return fileName == "."_L1 || fileName == ".."_L1;
347}
348
349void QDirListingPrivate::checkAndPushDirectory(QDirEntryInfo &entryInfo)
350{
351 using F = QDirListing::IteratorFlag;
352 // If we're doing flat iteration, we're done.
353 if (!iteratorFlags.testAnyFlags(F::Recursive))
354 return;
355
356 // Follow symlinks only when asked
357 if (!iteratorFlags.testAnyFlags(F::FollowDirSymlinks) && entryInfo.isSymLink())
358 return;
359
360 // Never follow . and ..
361 if (isDotOrDotDot(entryInfo.fileName()))
362 return;
363
364 // No hidden directories unless requested
365 const bool includeHidden = iteratorFlags.testAnyFlags(QDirListing::IteratorFlag::IncludeHidden);
366 if (!includeHidden && entryInfo.isHidden())
367 return;
368
369 // Never follow non-directory entries
370 if (!entryInfo.isDir())
371 return;
372
373 pushDirectory(entryInfo);
374}
375
376/*!
377 \internal
378
379 This function returns \c true if the current entry matches the filters
380 (i.e., the current entry will be returned as part of the directory
381 iteration); otherwise, \c false is returned.
382*/
383bool QDirListingPrivate::matchesFilters(QDirEntryInfo &entryInfo) const
384{
385 using F = QDirListing::IteratorFlag;
386
387 const QString &fileName = entryInfo.fileName();
388 if (fileName.isEmpty())
389 return false;
390
391 // name filter
392#if QT_CONFIG(regularexpression)
393 const bool skipNameFilters = iteratorFlags.testAnyFlags(F::NoNameFiltersForDirs)
394 && entryInfo.isDir();
395 if (!skipNameFilters) {
396 if (!regexMatchesName(fileName))
397 return false;
398 }
399#endif // QT_CONFIG(regularexpression)
400
401 if (isDotOrDotDot(fileName))
402 return iteratorFlags.testFlags(F::IncludeDotAndDotDot);
403
404 if (!iteratorFlags.testAnyFlag(F::IncludeHidden) && entryInfo.isHidden())
405 return false;
406
407 const bool includeBrokenSymlinks = iteratorFlags.testAnyFlags(F::IncludeBrokenSymlinks);
408 if (includeBrokenSymlinks && entryInfo.isSymLink() && !entryInfo.exists())
409 return true;
410
411 if (iteratorFlags.testFlag(F::ResolveSymlinks)) {
412 if (entryInfo.isSymLink() && !entryInfo.exists())
413 return false; // Exclude broken symlinks; anything else will be filtered below
414 } else {
415 constexpr auto f = F::ExcludeFiles | F::ExcludeDirs | F::ExcludeOther;
416 const bool filterByTargetType = iteratorFlags.testAnyFlags(f);
417 if (filterByTargetType && entryInfo.isSymLink())
418 return false;
419 }
420
421 if (iteratorFlags.testAnyFlag(F::ExcludeOther)
422 && !entryInfo.isFile() && !entryInfo.isDir() && !entryInfo.isSymLink()) {
423 return false;
424 }
425
426 if (iteratorFlags.testAnyFlags(F::ExcludeDirs) && entryInfo.isDir())
427 return false;
428
429 if (iteratorFlags.testAnyFlags(F::ExcludeFiles) && entryInfo.isFile())
430 return false;
431
432 return true;
433}
434
436{
437 if (engine)
438 return !fileEngineIterators.empty();
439
440#if !defined(QT_NO_FILESYSTEMITERATOR)
441 return !nativeIterators.empty();
442#endif
443
444 return false;
445}
446
447/*!
448 Constructs a QDirListing that can iterate over \a path.
449
450 You can pass options via \a flags to control how the directory should
451 be iterated.
452
453 By default, \a flags is IteratorFlag::Default.
454
455 \sa IteratorFlags
456*/
457QDirListing::QDirListing(const QString &path, IteratorFlags flags)
458 : d(new QDirListingPrivate)
459{
460 d->initialEntryInfo.entry = QFileSystemEntry(path);
461 d->iteratorFlags = flags;
462 d->init();
463}
464
465/*!
466 Constructs a QDirListing that can iterate over \a path.
467
468 You can pass options via \a flags to control how the directory should
469 be iterated. By default, \a flags is IteratorFlag::Default.
470
471 The listed entries will be filtered according to the file glob patterns
472 in \a nameFilters, which are converted to a regular expression using
473 QRegularExpression::fromWildcard (see QDir::setNameFilters() for more
474 details).
475
476 For example, the following iterator could be used to iterate over audio
477 files:
478
479 \snippet code/src_corelib_io_qdirlisting.cpp 2
480
481 Sometimes you can filter by name more efficiently by iterating over the
482 entries with a range-for loop, using string comparison. For example:
483
484 \snippet code/src_corelib_io_qdirlisting.cpp 7
485
486 \sa IteratorFlags, QDir::setNameFilters()
487*/
488QDirListing::QDirListing(const QString &path, const QStringList &nameFilters, IteratorFlags flags)
489 : d(new QDirListingPrivate)
490{
491 d->initialEntryInfo.entry = QFileSystemEntry(path);
492 d->nameFilters = nameFilters;
493 d->iteratorFlags = flags;
494 d->init();
495}
496
497/*!
498 \fn QDirListing::QDirListing(QDirListing &&other)
499
500 Move constructor. Moves \a other into this QDirListing.
501
502//! [partially-formed]
503 \note The moved-from object \a other is placed in a partially-formed state,
504 in which the only valid operations are destruction and assignment of a new
505 value.
506//! [partially-formed]
507*/
508
509/*!
510 \fn QDirListing &QDirListing::operator=(QDirListing &&other)
511
512 Move-assigns \a other to this QDirListing.
513
514 \include qdirlisting.cpp partially-formed
515*/
516
517/*!
518 Destroys the QDirListing.
519*/
520QDirListing::~QDirListing()
521{
522 delete d;
523}
524
525/*!
526 Returns the directory path used to construct this QDirListing.
527*/
528QString QDirListing::iteratorPath() const
529{
530 return d->initialEntryInfo.filePath();
531}
532
533/*!
534 Returns the set of IteratorFlags used to construct this QDirListing.
535*/
536QDirListing::IteratorFlags QDirListing::iteratorFlags() const
537{
538 return d->iteratorFlags;
539}
540
541/*!
542 Returns the list of file name glob filters used to construct this
543 QDirListing.
544*/
545QStringList QDirListing::nameFilters() const
546{
547 return d->nameFilters;
548}
549
550/*!
551 \class QDirListing::const_iterator
552 \since 6.8
553 \inmodule QtCore
554 \ingroup io
555
556 The iterator type returned by QDirListing::cbegin().
557
558//! [dirlisting-iterator-behavior]
559 \list
560 \li This is a forward-only, single-pass iterator (you cannot iterate
561 directory entries in reverse order)
562 \li Can't be copied, only \c{std::move()}d.
563 \li \include qdirlisting.cpp post-increment-partially-formed
564 \li Doesn't allow random access
565 \li Can be used in ranged-for loops; or with C++20 std::ranges algorithms
566 that don't require random access iterators
567 \li Dereferencing a valid iterator returns a \c{const DirEntry &}
568 \li (c)end() returns a \l QDirListing::sentinel that signals the end of
569 the iteration. Dereferencing an iterator that compares equal to end()
570 is undefined behavior
571 \endlist
572//! [dirlisting-iterator-behavior]
573
574 \include qdirlisting.cpp ranges-algorithms-note
575
576 \sa QDirListing, QDirListing::sentinel, QDirListing::DirEntry
577*/
578
579/*!
580 \typealias QDirListing::const_iterator::reference
581
582 A typedef for \c {const QDirListing::DirEntry &}.
583*/
584
585/*!
586 \typealias QDirListing::const_iterator::pointer
587
588 A typedef for \c {const QDirListing::DirEntry *}.
589*/
590
591/*!
592 \class QDirListing::sentinel
593 \since 6.8
594 \inmodule QtCore
595 \ingroup io
596
597 \l QDirListing returns an object of this type to signal the end of
598 iteration. Dereferencing a \l QDirListing::const_iterator that is
599 equal to \c sentinel{} is undefined behavior.
600
601 \include qdirlisting.cpp ranges-algorithms-note
602
603 \sa QDirListing, QDirListing::const_iterator, QDirListing::DirEntry
604*/
605
606/*!
607 \fn QDirListing::const_iterator QDirListing::begin() const
608 \fn QDirListing::const_iterator QDirListing::cbegin() const
609 \fn QDirListing::sentinel QDirListing::end() const
610 \fn QDirListing::sentinel QDirListing::cend() const
611
612 (c)begin() returns a QDirListing::const_iterator that can be used to
613 iterate over directory entries.
614
615 \include qdirlisting.cpp dirlisting-iterator-behavior
616
617 \note Each time (c)begin() is called on the same QDirListing object,
618 the internal state is reset and the iteration starts anew.
619
620 (Some of the above restrictions are dictated by the underlying system
621 library functions' implementation).
622
623 For example:
624 \snippet code/src_corelib_io_qdirlisting.cpp 0
625
626 Here's how to find and read all files filtered by name, recursively:
627 \snippet code/src_corelib_io_qdirlisting.cpp 1
628
629//! [ranges-algorithms-note]
630 \note The "classical" STL algorithms don't support iterator/sentinel, so
631 you need to use C++20 std::ranges algorithms for QDirListing, or else a
632 3rd-party library that provides range-based algorithms in C++17.
633//! [ranges-algorithms-note]
634
635 \sa QDirListing::DirEntry
636*/
638{
640 const_iterator it{d};
641 ++it;
642 return it;
643}
644
645/*!
646 \fn const QDirListing::DirEntry &QDirListing::const_iterator::operator*() const
647
648 Returns a \c{const QDirListing::DirEntry &} of the directory entry this
649 iterator points to.
650*/
651
652/*!
653 \fn const QDirListing::DirEntry *QDirListing::const_iterator::operator->() const
654
655 Returns a \c{const QDirListing::DirEntry *} to the directory entry this
656 iterator points to.
657*/
658
659/*!
660 \fn QDirListing::const_iterator::operator++()
661
662 Pre-increment operator.
663 Advances the iterator and returns a reference to it.
664*/
665
666/*!
667 \fn void QDirListing::const_iterator::operator++(int)
668
669 Post-increment operator.
670
671 \include qdirlisting.cpp std-input-iterator-tag
672
673//! [post-increment-partially-formed]
674 The return value of post-increment on objects that model
675 \c std::input_iterator is partially-formed (a copy of an iterator that
676 has since been advanced), the only valid operations on such an object
677 are destruction and assignment of a new iterator. Therefore the
678 post-increment operator advances the iterator and returns \c void.
679//! [post-increment-partially-formed]
680*/
681
682/*!
683 \internal
684
685 Implements the actual advancing. Not a member function to avoid forcing
686 DirEntry objects (and therefore const_iterator ones) onto the stack.
687*/
688auto QDirListing::next(DirEntry dirEntry) -> DirEntry
689{
690 dirEntry.dirListPtr->advance();
691 if (!dirEntry.dirListPtr->hasIterators())
692 return {}; // All done, make `this` equal to the end() iterator
693 return dirEntry;
694}
695
696/*!
697 \class QDirListing::DirEntry
698 \inmodule QtCore
699 \ingroup io
700
701 Dereferencing a valid QDirListing::const_iterator returns a DirEntry
702 object.
703
704 DirEntry offers a subset of QFileInfo's API (for example, fileName(),
705 filePath(), exists()). Internally, DirEntry only constructs a QFileInfo
706 object if needed, that is, if the info hasn't been already fetched
707 by other system functions. You can use DirEntry::fileInfo() to get a
708 QFileInfo. For example:
709
710 \snippet code/src_corelib_io_qdirlisting.cpp 3
711
712 \snippet code/src_corelib_io_qdirlisting.cpp 4
713*/
714
715/*!
716 \fn QFileInfo QDirListing::DirEntry::fileInfo() const
717 \fn QString QDirListing::DirEntry::fileName() const
718 \fn QString QDirListing::DirEntry::baseName() const
719 \fn QString QDirListing::DirEntry::completeBaseName() const
720 \fn QString QDirListing::DirEntry::suffix() const
721 \fn QString QDirListing::DirEntry::bundleName() const
722 \fn QString QDirListing::DirEntry::completeSuffix() const
723 \fn QString QDirListing::DirEntry::filePath() const
724 \fn QString QDirListing::DirEntry::canonicalFilePath() const
725 \fn QString QDirListing::DirEntry::absoluteFilePath() const
726 \fn QString QDirListing::DirEntry::absolutePath() const
727 \fn bool QDirListing::DirEntry::isDir() const
728 \fn bool QDirListing::DirEntry::isFile() const
729 \fn bool QDirListing::DirEntry::isSymLink() const
730 \fn bool QDirListing::DirEntry::exists() const
731 \fn bool QDirListing::DirEntry::isHidden() const
732 \fn bool QDirListing::DirEntry::isReadable() const
733 \fn bool QDirListing::DirEntry::isWritable() const
734 \fn bool QDirListing::DirEntry::isExecutable() const
735 \fn qint64 QDirListing::DirEntry::size() const
736 \fn QDateTime QDirListing::DirEntry::fileTime(QFile::FileTime type, const QTimeZone &tz) const
737 \fn QDateTime QDirListing::DirEntry::birthTime(const QTimeZone &tz) const;
738 \fn QDateTime QDirListing::DirEntry::metadataChangeTime(const QTimeZone &tz) const;
739 \fn QDateTime QDirListing::DirEntry::lastModified(const QTimeZone &tz) const;
740 \fn QDateTime QDirListing::DirEntry::lastRead(const QTimeZone &tz) const;
741
742 See the QFileInfo methods with the same names.
743*/
744
745QFileInfo QDirListing::DirEntry::fileInfo() const
746{
747 return dirListPtr->currentEntryInfo.fileInfo();
748}
749
750QString QDirListing::DirEntry::fileName() const
751{
752 return dirListPtr->currentEntryInfo.fileName();
753}
754
755QString QDirListing::DirEntry::baseName() const
756{
757 return dirListPtr->currentEntryInfo.baseName();
758}
759
760QString QDirListing::DirEntry::completeBaseName() const
761{
762 return dirListPtr->currentEntryInfo.completeBaseName();
763}
764
765QString QDirListing::DirEntry::suffix() const
766{
767 return dirListPtr->currentEntryInfo.suffix();
768}
769
770QString QDirListing::DirEntry::bundleName() const
771{
772 return dirListPtr->currentEntryInfo.bundleName();
773}
774
775QString QDirListing::DirEntry::completeSuffix() const
776{
777 return dirListPtr->currentEntryInfo.completeSuffix();
778}
779
780QString QDirListing::DirEntry::filePath() const
781{
782 return dirListPtr->currentEntryInfo.filePath();
783}
784
785QString QDirListing::DirEntry::canonicalFilePath() const
786{
787 return dirListPtr->currentEntryInfo.canonicalFilePath();
788}
789
790QString QDirListing::DirEntry::absoluteFilePath() const
791{
792 return dirListPtr->currentEntryInfo.absoluteFilePath();
793}
794
795QString QDirListing::DirEntry::absolutePath() const
796{
797 return dirListPtr->currentEntryInfo.absolutePath();
798}
799
801{
802 return dirListPtr->currentEntryInfo.isDir();
803}
804
806{
807 return dirListPtr->currentEntryInfo.isFile();
808}
809
811{
812 return dirListPtr->currentEntryInfo.isSymLink();
813}
814
816{
817 return dirListPtr->currentEntryInfo.exists();
818}
819
821{
822 return dirListPtr->currentEntryInfo.isHidden();
823}
824
826{
827 return dirListPtr->currentEntryInfo.isReadable();
828}
829
831{
832 return dirListPtr->currentEntryInfo.isWritable();
833}
834
836{
837 return dirListPtr->currentEntryInfo.isExecutable();
838}
839
840qint64 QDirListing::DirEntry::size() const
841{
842 return dirListPtr->currentEntryInfo.size();
843}
844
845QDateTime QDirListing::DirEntry::fileTime(QFile::FileTime type, const QTimeZone &tz) const
846{
847 return dirListPtr->currentEntryInfo.fileTime(type, tz);
848}
849
850QT_END_NAMESPACE
bool entryMatches(QDirEntryInfo &info)
QDirListing::IteratorFlags iteratorFlags
void pushInitialDirectory()
QStringList nameFilters
void checkAndPushDirectory(QDirEntryInfo &info)
std::unique_ptr< QAbstractFileEngine > engine
QDuplicateTracker< QString > visitedLinks
bool hasIterators() const
vector_stack< FsIteratorPtr > nativeIterators
vector_stack< FEngineIteratorPtr > fileEngineIterators
bool matchesFilters(QDirEntryInfo &data) const
QDirEntryInfo initialEntryInfo
QDirEntryInfo currentEntryInfo
void pushDirectory(QDirEntryInfo &info)
\inmodule QtCore
Definition qdirlisting.h:72
Q_CORE_EXPORT bool isReadable() const
Q_CORE_EXPORT bool isHidden() const
Q_CORE_EXPORT bool isWritable() const
Q_CORE_EXPORT bool isExecutable() const
Q_CORE_EXPORT bool isFile() const
Q_CORE_EXPORT bool exists() const
Q_CORE_EXPORT bool isSymLink() const
Q_CORE_EXPORT bool isDir() const
const_iterator & operator++()
Pre-increment operator.
static bool isDotOrDotDot(QStringView fileName)