1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
|
The tt(filesystem) namespace has two classes simplifying directory
processing: objects of the class tt(directory_iterator) are (input) iterators
iterating over the entries of directories; and objects of the class
tt(recursive_directory_iterator) are (input) iterators recursively visiting
all entries of directories.location
bf(enum class directory_options)
The tt(enum class directory_options)hi(directory_options) defines values that
are used to fine-tune the behavior of tt(recursive_directory_iterator)
objects, supporting bitwise operators (the values of its symbols are shown
between parentheses):
itemization(
itt(none) (0): directory symlinks are skipped, denied permission to enter
a sub-directory generates an error;
itt(follow_directory_symlink) (1): symlinks to sub-directories are
followed;
itt(skip_permission_denied) (2): directories that cannot be entered are
silently skipped.
)
bf(Constructors):
itemization(
ittq((recursive_)directory_iterator())
(the end-iterator of the tt((recursive_)directory_iterator's)
iterator-range;)
ittq((recursive_)directory_iterator(path const &from [, error_code &ec]))
(constructs a tt((recursive-)directory_iterator) using tt(from) as the
starting directory of the iterator. All members of standard input
iterators (cf. section ref(ITERATORS)) are supported;)
ittq(recursive_directory_iterator(path const &from, directory_options opts
[, error_code &ec]))
(constructs a tt((recursive-)directory_iterator) fine-tuning its
behavior to the options specified by tt(opts).)
)
Copy, and move constructors are available.
These iterators point to tt(directory_entry) objects referring to
entries in the computer's file system. E.g.,
verb( cout << *directory_iterator{ "/home" } << '\n';
// shows the first entry under /home )
tt((Recursive_)directory_iterators) can be used with range-based for-loops
and in standard tt(for) and tt(while) statements.
COMMENT(
After constructing a tt((recursive_)directory_iterator base{"/var/log"})
object it refers to the first element of its directory. Such iterators can
also explicitly be defined: tt(auto &iter = begin(base), auto iter =
begin(base), auto &iter = base) or tt(auto iter = base). All these tt(iter)
objects refer to tt(base's) data, and incrementing them also advances
tt(base) to its next element:
verb( recursive_directory_iterator base{ "/var/log/" };
auto iter = base;
// final two elements show identical paths,
// different from the first element.
cout << *iter << ' ' << *++iter << ' ' << *base << '\n';)
The functions tt(begin) and tt(end) that are used in the above examples
are, like tt((recursive_)directory_iterator), available in the tt(filesystem)
namespace.
END)
bf(Additional members of recursive_directory_iterators)
itemization(
ithtq(depth)(int depth() const)
(returns the current iteration depth. The depth of the initial
directory, specified at construction-time, equals 0;)
ithtq(disable_recursion_pending)(void disable_recursion_pending())
(when called before incrementing the iterator the next directory entry
is not recursively visited. Once the iterator is incremented recursion
is again allowed. If a recursion should end at a specific depth then
once tt(depth()) returns that specific depth this member must be
called each time before the iterator's increment operator is called;)
ithtq(increment)(recursive_directory_iterator &increment(error_code &ec))
(acts identically to the iterator's increment operator. However, at
errors tt(operator++) throws a tt(filesystem_error) exception, while
tt(increment) assigns the error to tt(ec);)
ithtq(options)(directory_options options() const)
(returns the option(s) specified at construction-time;)
ithtq(pop)(void pop())
(ends processing the current directory, and continues at the next
entry in the current directory's parent;)
ithtq(recursion_pending)(bool recursion_pending() const)
(tt(true) is returned if recursive processing of sub-directories of the
currently processed directory is allowed. If so, and the
the iterator points at a sub-directory, then processing
continues in that sub-directory at the iterator's next increment;)
)
Here's a small program displaying all elements and
all immediate sub-directories of a directory:
verbinsert(-s4 //demo examples/recurs.cc)
The above program handles entries as they come. Other strategies must be
implemented `by hand'. E.g., a breadth-first strategy first visits all the
non-directory entries and then visits the sub-directories, as illustrated in
the next example by processingthe directories stored in tt(level) in turn
(initially it merely contains the starting directory).
`Processing a directory' means that its non-directory entries are directly
processed storing the names of sub-directories in tt(next). Once
all entries at tt(level) have been processed the names of the next level
sub-directories are available (in tt(next)). By assigning tt(next) to
tt(level) all directories at the next level are processed. When reaching the
most deeply nested sub-directories its tt(next) is empty and the tt(while)
statement ends:
verbinsert(-s4 //code examples/breadth.cc)
|