QDirListing Class | Qt Core | Qt 6.11.1
Description: The QDirListing class provides an STL-style iterator for directory entries.

- Qt 6.11
- Qt Core
- C++ Classes
- QDirListing
- Qt 6.11.1 Reference Documentation

# QDirListing Class

The QDirListing class provides an STL-style iterator for directory entries. More...

Header: | `#include <QDirListing>`
CMake: | `find_package(Qt6 REQUIRED COMPONENTS Core)` `target_link_libraries(mytarget PRIVATE Qt6::Core)`
qmake: | `QT += core`
Since: | Qt 6.8

- List of all members, including inherited members
- QDirListing is part of Input/Output and Networking.

## Public Types

class | DirEntry
`(since 6.8)` class | const_iterator
`(since 6.8)` class | sentinel
enum class | IteratorFlag { Default, ExcludeFiles, ExcludeDirs, ExcludeOther, ResolveSymlinks, …, FollowDirSymlinks }
flags | IteratorFlags

## Public Functions

| QDirListing(const QString &path, QDirListing::IteratorFlags flags = IteratorFlag::Default)
| QDirListing(const QString &path, const QStringList &nameFilters, QDirListing::IteratorFlags flags = IteratorFlag::Default)
| QDirListing(QDirListing &&other)
| ~QDirListing()
QDirListing::const_iterator | begin() const
QDirListing::const_iterator | cbegin() const
QDirListing::sentinel | cend() const
QDirListing::sentinel | end() const
QDirListing::IteratorFlags | iteratorFlags() const
QString | iteratorPath() const
QStringList | nameFilters() const
QDirListing & | operator=(QDirListing &&other)

## Detailed Description

You can use QDirListing to navigate entries of a directory one at a time. It is similar to QDir::entryList() and QDir::entryInfoList(), but because it lists entries one at a time instead of all at once, it scales better and is more suitable for large directories. It also supports listing directory contents recursively, and following symbolic links. Unlike QDir::entryList(), QDirListing does not support sorting.

The QDirListing constructor takes a directory path string as argument. Here's how to iterate over all entries recursively:

     using ItFlag = QDirListing::IteratorFlag;
     for (const auto &dirEntry : QDirListing(u"/etc"_s, ItFlag::Recursive)) {
         qDebug() << dirEntry.filePath();
         // /etc/.
         // /etc/..
         // /etc/X11
         // /etc/X11/fs
         // ...
     }

Here's how to find and read all regular files filtered by name, recursively:

     using F = QDirListing::IteratorFlag;
     QDirListing dirList(u"/sys"_s, QStringList{u"scaling_cur_freq"_s}, F::FilesOnly | F::Recursive);
     for (const auto &dirEntry : dirList) {
         QFile f(dirEntry.filePath());
         if (f.open(QIODevice::ReadOnly))
             qDebug() << f.fileName() << f.readAll().trimmed().toDouble() / 1000 << "MHz";
     }

Here's how to list only regular files, recursively:

     using F = QDirListing::IteratorFlag;
     const auto flags = F::FilesOnly | F::Recursive;
     for (const auto &dirEntry : QDirListing(u"/etc"_s, flags)) {
         // ...
     }

Here's how to list only regular files and symbolic links to regular files, recursively:

     using F = QDirListing::IteratorFlag;
     const auto flags = F::FilesOnly | F::Recursive | F::ResolveSymlinks;
     for (const auto &dirEntry : QDirListing(u"/etc"_s, flags)) {
         // ...
     }

QDirListing::const_iterator models C++20 std::input_iterator, that is, it is a move-only, forward-only, single-pass iterator, that doesn't allow random access. It can be used in ranged-for loops (or with C++20 range algorithms that don't require random access iterators). Dereferencing a valid iterator returns a QDirListing::DirEntry object. The (c)end() sentinel marks the end of the iteration. Dereferencing an iterator that is equal to sentinel is undefined behavior.

QDirListing::DirEntry offers a subset of QFileInfo's API (for example, fileName(), filePath(), exists()). Internally, DirEntry only constructs a QFileInfo object if needed, that is, if the info hasn't been already fetched by other system functions. You can use DirEntry::fileInfo() to get a QFileInfo. For example:

     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 implementation) the fileName could
         // be known already
         if (dirEntry.fileInfo().fileName().endsWith(u".conf")) { /* ... */ }
     }
     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 */) { /* ... */ }
     }

See also QDir and QDir::entryList().

## Member Type Documentation

### enum class QDirListing::IteratorFlag
flags QDirListing::IteratorFlags

This enum class describes flags that can be used to configure the behavior of QDirListing. Values from this enumerator can be bitwise OR'ed together.

Constant | Value | Description
--- | --- | ---
`QDirListing::IteratorFlag::Default` | `0x000000` | List all entries, that is, files, directories, symbolic links including broken symbolic links (where the target doesn't exist) and special (other) system files, see ExcludeOther for details. Hidden files and directories and the special entries `.` and `..` aren't listed by default.
`QDirListing::IteratorFlag::ExcludeFiles` | `0x000004` | Don't list regular files. When combined with ResolveSymlinks, symbolic links to regular files will be excluded too.
`QDirListing::IteratorFlag::ExcludeDirs` | `0x000008` | Don't list directories. When combined with ResolveSymlinks, symbolic links to directories will be excluded too.
`QDirListing::IteratorFlag::ExcludeOther` | `0x000010` | [since 6.10] Don't list file system entries that are not directories, regular files, or symbolic links. On Unix, a special (other) file system entry is a FIFO, socket, character device, or block device. For more details see the `mknod` manual page. On Windows (for historical reasons) `.lnk` files are considered special (other) file system entries.
`QDirListing::IteratorFlag::ResolveSymlinks` | `0x000020` | Filter symbolic links based on the type of the target of the link, rather than the symbolic link itself. Broken symbolic links (where the target doesn't exist) are excluded, set IncludeBrokenSymlinks to include them. This flag is ignored on operating systems that don't support symbolic links.
`QDirListing::IteratorFlag::IncludeBrokenSymlinks` | `0x001000` | [since 6.11] Lists broken symbolic links, where the target doesn't exist, regardless of the status of the ResolveSymlinks flag. This flag is ignored on operating systems that don't support symbolic links.
`QDirListing::IteratorFlag::FilesOnly` | `ExcludeDirs | ExcludeOther` | Only regular files will be listed. When combined with ResolveSymlinks, symbolic links to files will also be listed.
`QDirListing::IteratorFlag::DirsOnly` | `ExcludeFiles | ExcludeOther` | Only directories will be listed. When combined with ResolveSymlinks, symbolic links to directories will also be listed.
`QDirListing::IteratorFlag::IncludeHidden` | `0x000040` | List hidden entries. When combined with Recursive, the iteration will recurse into hidden sub-directories as well.
`QDirListing::IteratorFlag::IncludeDotAndDotDot` | `0x000080` | List the `.` and `..` special entries.
`QDirListing::IteratorFlag::CaseSensitive` | `0x000100` | The file glob patterns in the name filters passed to the QDirListing constructor, will be matched case sensitively (for details, see QDir::setNameFilters()).
`QDirListing::IteratorFlag::Recursive` | `0x000400` | List entries inside all sub-directories as well. When combined with FollowDirSymlinks, symbolic links to directories will be iterated too.
`QDirListing::IteratorFlag::FollowDirSymlinks` | `0x000800` | When combined with Recursive, symbolic links to directories will be iterated too. Symbolic link loops (e.g., link => . or link => ..) are automatically detected and ignored.

The IteratorFlags type is a typedef for QFlags<IteratorFlag>. It stores an OR combination of IteratorFlag values.

## Member Function Documentation

### `[explicit]` QDirListing::QDirListing(const QString &path, QDirListing::IteratorFlags flags = IteratorFlag::Default)

Constructs a QDirListing that can iterate over path.

You can pass options via flags to control how the directory should be iterated.

By default, flags is IteratorFlag::Default.

See also IteratorFlags.

### `[explicit]` QDirListing::QDirListing(const QString &path, const QStringList &nameFilters, QDirListing::IteratorFlags flags = IteratorFlag::Default)

Constructs a QDirListing that can iterate over path.

You can pass options via flags to control how the directory should be iterated. By default, flags is IteratorFlag::Default.

The listed entries will be filtered according to the file glob patterns in nameFilters, which are converted to a regular expression using QRegularExpression::fromWildcard (see QDir::setNameFilters() for more details).

For example, the following iterator could be used to iterate over audio files:

     QDirListing audioFileIt(u"/home/johndoe/"_s, QStringList{u"*.mp3"_s, u"*.wav"_s},
                             QDirListing::IteratorFlag::FilesOnly);

Sometimes you can filter by name more efficiently by iterating over the entries with a range-for loop, using string comparison. For example:

         using F = QDirListing::IteratorFlag;
         const auto flags = F::FilesOnly | F::Recursive | F::ResolveSymlinks;
         for (const auto &dirEntry : QDirListing(u"/usr"_s, flags)) {
             // Faster than using name filters, filter ".txt" and ".html" files
             // using QString API
             const QString fileName = dirEntry.fileName();
             if (fileName.endsWith(".txt"_L1) || fileName.endsWith(".html"_L1)) {
                 // ...
             }
         }
     }

See also IteratorFlags and QDir::setNameFilters().

### `[noexcept]` QDirListing::QDirListing(QDirListing &&other)

Move constructor. Moves other into this QDirListing.

Note: The moved-from object other is placed in a partially-formed state, in which the only valid operations are destruction and assignment of a new value.

### `[noexcept]` QDirListing::~QDirListing()

Destroys the QDirListing.

### QDirListing::const_iterator QDirListing::begin() const

### QDirListing::const_iterator QDirListing::cbegin() const

### QDirListing::sentinel QDirListing::end() const

### QDirListing::sentinel QDirListing::cend() const

(c)begin() returns a QDirListing::const_iterator that can be used to iterate over directory entries.

- This is a forward-only, single-pass iterator (you cannot iterate directory entries in reverse order)
- Can't be copied, only `std::move()`d.
- The return value of post-increment on objects that model `std::input_iterator` is partially-formed (a copy of an iterator that has since been advanced), the only valid operations on such an object are destruction and assignment of a new iterator. Therefore the post-increment operator advances the iterator and returns `void`.
- Doesn't allow random access
- Can be used in ranged-for loops; or with C++20 std::ranges algorithms that don't require random access iterators
- Dereferencing a valid iterator returns a `const DirEntry &`
- (c)end() returns a QDirListing::sentinel that signals the end of the iteration. Dereferencing an iterator that compares equal to end() is undefined behavior

Note: Each time (c)begin() is called on the same QDirListing object, the internal state is reset and the iteration starts anew.

(Some of the above restrictions are dictated by the underlying system library functions' implementation).

For example:

     using ItFlag = QDirListing::IteratorFlag;
     for (const auto &dirEntry : QDirListing(u"/etc"_s, ItFlag::Recursive)) {
         qDebug() << dirEntry.filePath();
         // /etc/.
         // /etc/..
         // /etc/X11
         // /etc/X11/fs
         // ...
     }

Here's how to find and read all files filtered by name, recursively:

     using F = QDirListing::IteratorFlag;
     QDirListing dirList(u"/sys"_s, QStringList{u"scaling_cur_freq"_s}, F::FilesOnly | F::Recursive);
     for (const auto &dirEntry : dirList) {
         QFile f(dirEntry.filePath());
         if (f.open(QIODevice::ReadOnly))
             qDebug() << f.fileName() << f.readAll().trimmed().toDouble() / 1000 << "MHz";
     }

Note: The "classical" STL algorithms don't support iterator/sentinel, so you need to use C++20 std::ranges algorithms for QDirListing, or else a 3rd-party library that provides range-based algorithms in C++17.

See also QDirListing::DirEntry.

### QDirListing::IteratorFlags QDirListing::iteratorFlags() const

Returns the set of IteratorFlags used to construct this QDirListing.

### QString QDirListing::iteratorPath() const

Returns the directory path used to construct this QDirListing.

### QStringList QDirListing::nameFilters() const

Returns the list of file name glob filters used to construct this QDirListing.

### `[noexcept]` QDirListing &QDirListing::operator=(QDirListing &&other)

Move-assigns other to this QDirListing.

Note: The moved-from object other is placed in a partially-formed state, in which the only valid operations are destruction and assignment of a new value.