Boost C++ Libraries

PrevUpHomeNext

Class directory_iterator

boost::filesystem::directory_iterator — Objects of type directory_iterator provide standard library compliant iteration over the contents of a directory.

Synopsis

// In header: <boost/filesystem/directory.hpp>


class directory_iterator : public boost::iterator_facade< directory_iterator, directory_entry, boost::single_pass_traversal_tag >
{
public:

  // public member functions
  directory_iterator() noexcept;
  directory_iterator(path const &, directory_options, system::error_code &) noexcept;
  directory_iterator(path const &, system::error_code &) noexcept;
  explicit directory_iterator(path const &, 
                              directory_options = directory_options::none);
  directory_iterator(directory_iterator const &) = default;
  directory_iterator & operator=(directory_iterator const &) = default;
  directory_iterator(directory_iterator &&) noexcept;
  directory_iterator & operator=(directory_iterator &&) noexcept;
  directory_iterator & increment(system::error_code &);
  directory_iterator & operator++();
  directory_entry const & operator*() const noexcept;
  const directory_entry * operator->() const noexcept;
  bool operator==(directory_iterator const &) const noexcept;
  bool operator!=(directory_iterator const &) const noexcept;
};

Description

directory_iterator satisfies the requirements of an input iterator (C++ Std, 24.2.1, Input iterators [input.iterators]).

A directory_iterator reads successive elements from the directory for which it was constructed, as if by calling ISO/IEC 9945 readdir() or readdir_r(). After a directory_iterator is constructed, and every time operator++ is called, it reads a directory element and stores information about it in an object of type directory_entry.

operator++ is not equality preserving; that is, i == j does not imply that ++i == ++j.

[Note] Note

The practical consequence of not preserving equality is that directory iterators can only be used for single-pass algorithms.

If the end of the directory elements is reached, the iterator shall become equal to the end iterator value. The constructor directory_iterator() with no arguments always constructs an end iterator object, which shall be the only valid iterator for the end condition. Invoking operator* on an end iterator has undefined behavior. For any other iterator value a const directory_entry& is returned. Similarly, invoking operator-> on an end iterator results in undefined behavior. For any other iterator value a const directory_entry* is returned.

Two end iterators are always equal. An end iterator is never equal to a non-end iterator.

The result of calling the path() member of the directory_entry object obtained by dereferencing a directory_iterator is a reference to a path object composed of the directory argument from which the iterator was constructed with filename of the directory entry appended as if by operator/=.

Directory iteration shall not yield directory entries for the current (dot) and parent (dot dot) directories.

The order of directory entries obtained by dereferencing successive increments of a directory_iterator is unspecified. The order may also be different between different iterations over the same directory.

[Note] Note

Programs performing directory iteration may wish to test if the path obtained by dereferencing a directory iterator actually exists. It could be a symbolic link to a non-existent file. Programs recursively walking directory trees for purposes of removing and renaming entries may wish to avoid following symbolic links.

If a file is removed from or added to a directory after the construction of a directory_iterator for the directory, it is unspecified whether or not subsequent incrementing of the iterator will ever result in an iterator whose value is the removed or added directory entry. See ISO/IEC 9945 readdir().

directory_iterator objects maintain an internal shared state. When a directory_iterator is copied, the copy refers to the same state as the original. Dereferencing the copy produces the same directory entry as the original. It is unspecified whether modifying a directory iterator or its directory entry affects other directory iterators referring to the same shared state. Concurrently accessing multiple iterators referring to the same shared state results in undefined behavior.

[Note] Note

Dereferencing a directory_iterator returns a reference to directory_entry, which may be stored in the shared state. Many methods of directory_entry may update cached information stored in the entry, which would constitute a data race if done concurrently in multiple threads.

[Note] Note

Until C++17, iterators are required to be copyable. In C++20 and later, iterator concepts no longer require copyability, but much of the existing code still assumes iterators are copyable. On the other hand, ISO/IEC 9945 readdir() and the equivalent Windows APIs don't support deep copying of the directory iteration state. This necessitates the shared state design, along with the caveats described above. Future operating systems may support copying directory iteration state, which would allow for a simpler and more natural design of the iterator.

Users are advised to avoid using multiple copies of the same directory iterator and relying on the shared state effects. Prefer move operations for passing directory iterators and construct separate directory iterators from paths when independent iterators are needed.

See Also: recursive_directory_iterator.

directory_iterator public member functions

  1. directory_iterator() noexcept;
    Default constructor.

    Effects: Constructs the end iterator.

  2. directory_iterator(path const & p, directory_options opts, 
                       system::error_code & ec) noexcept;
    Constructs an iterator representing the first entry in the directory.

    Effects: 

    Constructs an iterator representing the first entry in the directory p resolves to, if any; otherwise, the end iterator.

    If opening the directory fails with a permission_denied error and (opts & directory_options::skip_permission_denied) != 0, constructs the end iterator and ignores the error.

    For the overloads taking ec, an end iterator is constructed in case of error.

    [Note] Note

    To iterate over the current directory, use directory_iterator(".") rather than directory_iterator("").

    Parameters:

    p

    Path to directory to iterate over.

    opts

    Directory iteration options. directory_options::none if not specified.

    ec

    Error code returned in case of failure.

    Postconditions:

    Unless the end iterator was constructed, *this points to the first entry.

  3. directory_iterator(path const & p, system::error_code & ec) noexcept;

    This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

  4. explicit directory_iterator(path const & p, 
                                directory_options opts = directory_options::none);

    This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

  5. directory_iterator(directory_iterator const & that) = default;
    Copy constructor.

    Effects: 

    If that is an end iterator, creates an end iterator. Otherwise, creates an iterator referring to the same shared state as that.

    Parameters:

    that

    Iterator to copy from.

    Postconditions:

    *this == that.

  6. directory_iterator & operator=(directory_iterator const & that) = default;
    Copy assignment operator.

    Effects: 

    If that is an end iterator, makes *this equal to end iterator. Otherwise, makes *this refer to the same shared state as that.

    Parameters:

    that

    Iterator to copy from.

    Postconditions:

    *this == that.

    Returns:

    *this.

  7. directory_iterator(directory_iterator && that) noexcept;
    Move constructor.

    Effects: 

    If that is an end iterator, creates an end iterator. Otherwise, creates an iterator referring to the same shared state as that.

    Parameters:

    that

    Iterator to move from.

    Postconditions:

    *this is equal to the original value of that, that == directory_iterator().

  8. directory_iterator & operator=(directory_iterator && that) noexcept;
    Move assignment operator.

    Effects: 

    If that is an end iterator, makes *this equal to end iterator. Otherwise, makes *this refer to the same shared state as that.

    Parameters:

    that

    Iterator to move from.

    Postconditions:

    *this is equal to the original value of that, that == directory_iterator().

    Returns:

    *this.

  9. directory_iterator & increment(system::error_code & ec);
    Advances the iterator to the next directory entry.

    Effects: 

    As specified by the C++ Standard, 24.1.1 Input iterators [input.iterators]. In case of error the iterator is left in the end state.

    Parameters:

    ec

    Error code returned in case of failure.

    Returns:

    *this.

  10. directory_iterator & operator++();
    Advances the iterator to the next directory entry.

    Effects: 

    As specified by the C++ Standard, 24.1.1 Input iterators [input.iterators].

    See Also: increment.

    Returns:

    *this.

  11. directory_entry const & operator*() const noexcept;
    Dereferences the iterator.

    Returns:

    The directory entry referenced by the iterator.

  12. const directory_entry * operator->() const noexcept;
    Indirection operator of the iterator.

    Returns:

    The directory entry referenced by the iterator.

  13. bool operator==(directory_iterator const & that) const noexcept;
    Compares two directory iterators for equivalence.

    Parameters:

    that

    Directory iterator to compare with.

    Returns:

    true if both *this and that are end iterators or refer to the same shared state, otherwise false.

  14. bool operator!=(directory_iterator const & that) const noexcept;
    Compares two directory iterators for inequivalence.

    Parameters:

    that

    Directory iterator to compare with.

    Returns:

    !(*this == that).


PrevUpHomeNext