diff options
author | Ahmad Samir <a.samirh78@gmail.com> | 2024-01-30 15:22:30 +0200 |
---|---|---|
committer | Ahmad Samir <a.samirh78@gmail.com> | 2024-02-29 16:35:57 +0200 |
commit | c39a0d1e8956e042139ce3065681e4c5d07412f3 (patch) | |
tree | ee38f631e5bd345cdbd634bd31a1a575bf461159 /src/corelib/doc | |
parent | 78c33a77414585b39c2c3fa14d1c88d6af7c03f1 (diff) |
Add QDirListing, an STL-style iterator for directory entries
This class offers a forward-only const_iterator, that matches the system
low-level functions' logic (e.g. readdir()/dirstream logic). This
iterator is a std::input_iterator_tag.
QDirIterator uses Java-style iterators that have a couple of issues:
- They don't fit the logic of the underlying native system functions
(readdir()/__dirstream and co.), there is no way to know if there is a
next entry except by advancing the iterator (calling readdir()) first
- As a consequence of the above, two QFileInfo objects, current and next,
had to be used to fit that paradigm; and the code always
iterated/stat'ed an extra entry past the one we want, e.g. when
filtering
The next step is porting QAbstractFileEngineIterator and its subclasses
to be like QFileSystemIterator, i.e. replace hasNext()/next() with a `bool
advance()` virtual method. This is easier to reason about than the
Java-style iterators, and is more in-line with the new class.
Discussed-on: https://lists.qt-project.org/pipermail/development/2023-December/044745.html
Change-Id: I8e696cefdca18d8c78f803efdb83a73dd43eb720
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib/doc')
-rw-r--r-- | src/corelib/doc/snippets/code/src_corelib_io_qdirlisting.cpp | 58 |
1 files changed, 50 insertions, 8 deletions
diff --git a/src/corelib/doc/snippets/code/src_corelib_io_qdirlisting.cpp b/src/corelib/doc/snippets/code/src_corelib_io_qdirlisting.cpp index ec3f3adc50..231bf48d26 100644 --- a/src/corelib/doc/snippets/code/src_corelib_io_qdirlisting.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_io_qdirlisting.cpp @@ -1,11 +1,16 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +#include <QDirListing> + +using namespace Qt::StringLiterals; + +[[maybe_unused]] static void func() { +{ //! [0] -QDirIterator it("/etc", QDirIterator::Subdirectories); -while (it.hasNext()) { - QString dir = it.next(); - qDebug() << dir; +using ItFlag = QDirListing::IteratorFlag; +for (const auto &dirEntry : QDirListing(u"/etc"_s, ItFlag::Recursive)) { + qDebug() << dirEntry.filePath(); // /etc/. // /etc/.. // /etc/X11 @@ -13,16 +18,53 @@ while (it.hasNext()) { // ... } //! [0] +} +{ //! [1] -QDirIterator it("/sys", QStringList() << "scaling_cur_freq", QDir::NoFilter, QDirIterator::Subdirectories); -while (it.hasNext()) { - QFile f(it.next()); +using ItFlag = QDirListing::IteratorFlag; +QDirListing dirList(u"/sys"_s, QStringList{u"scaling_cur_freq"_s}, + QDir::NoFilter, ItFlag::Recursive); +for (const auto &dirEntry : dirList) { + QFile f(dirEntry.filePath()); f.open(QIODevice::ReadOnly); qDebug() << f.fileName() << f.readAll().trimmed().toDouble() / 1000 << "MHz"; } //! [1] +} +{ //! [2] -QDirIterator audioFileIt(audioPath, {"*.mp3", "*.wav"}, QDir::Files); +QDirListing audioFileIt(u"/home/johndoe/"_s, {"*.mp3", "*.wav"}, QDir::Files); //! [2] +} + +{ +//! [3] +using ItFlag = QDirListing::IteratorFlag; +for (const auto &dirEntry : QDirListing(u"/etc"_s, ItFlag::Recursive)) { + // Faster + if (dirEntry.fileName().endsWith(u".conf")) { /* ... */ } + + // This works, but might be potentially slower, since it has to construct a + // QFileInfo, whereas (depending on the implemnetation) the fileName could + // be known already + if (dirEntry.fileInfo().fileName().endsWith(u".conf")) { /* ... */ } +} +//! [3] +} + +{ +//! [4] +using ItFlag = QDirListing::IteratorFlag; +for (const auto &dirEntry : QDirListing(u"/etc"_s, ItFlag::Recursive)) { + // Both approaches are the same, because DirEntry will have to construct + // a QFileInfo to get this info (for example, by calling system stat()) + + if (dirEntry.size() >= 4'000 /* 4KB */) { /* ...*/ } + if (dirEntry.fileInfo().size() >= 4'000 /* 4KB */) { /* ... */ } +} +//! [4] +} + +} |