This ALib Module provides mechanics to scan directories and contained files. The scan results are collected in an instance of FTree, which inherits class StringTree. Using classes StringTree::Cursor and StringTree::RecursiveIterator, two very comfortable interfaces to accessing the results are available.
As of today, besides scanning files, no specific further functionality is given and it is up to the user of the module to do with the result lists whatever is intended.
While the reference documentation of the types found in this module is quite verbose and thus should be all that is really needed, this Programmer's Manual just provides some few step-by-step demo samples.
A simple application needs to include just header ALib.Files.H.
For scanning a path including its subdirectories, a few objects are needed:
Here are the links to the reference documentation of these objects:
Note that the sample code above uses preprocessor symbol ALIB_BASE_DIR, which is defined with the ALib unit test project, that this documentation uses to generate the samples.
That is all we needed to start the scan, which is done using namespace function ScanFiles. Next we use namespace function DbgDump, which as its prefix Dbg indicates, is only available in debug-compilations of the library:
The resulting output is:
You might wonder about the resultPath
vector given as an output parameter into function ScanFiles. Especially the question is: Why is it a vector? Wouldn't it be just the requested start path?
Let's quickly examine the result:
This writes:
So, in fact, it is only one result and it is here called "real path" is exactly the path that was requested to be scanned. But this can be quite different, when symbolic links come into place. Details on this topic is given in the with reference documentation of function ScanFiles and instead to repeat this here, we ask the reader for a brief digression to this explanation now.
We left all fields of class ScanParameters with their default values in the previous sample. Now we want to look at fields:
Again, please refer to the reference documentation of the fields linked above, to get a quick understanding, why the scan function offers to set up to three different filter objects.
Class FFilter is a very simple virtual abstract interface class, which only has one single method Includes to implement. Derived filter types, need return true
, if a file or directory "passes" the filter, hence in this case is included in the scan results.
It should be very straight forward to implement an own derived a filter class. The problem with such class would be, that it would be more or less "hard-coded" in respect to what is filtered and what not. This might be flexible enough for most applications.
The next chapter introduces a filter which is run-time compiled!
In case module ALib Expressions is included in the ALib Build, this module ALib Files exposes the FileExpressions class, which implements a CompilerPlugin that allows articulate run-time expressions working with FInfo objects.
The class exposes the public inner type FileExpressions::Filter which implements the FFilter interface. With construction, the filter accepts a character string containing the filter expression.
The full set of expression operators, functions and constants is documented with class FileExpressions and not to be repeated here. While expressions might return any kind of type, those used with class FileExpression::Filter, have to evaluate to a boolean value. As documented with module ALib Expressions, due to the type-safe implementation of the module, already at "compile time" of an expression (which is run-time of your software), the result type of an expression can be checked.
We just look at some samples:
We have to add the header-file ALib.Files.Expressions.H:
Now this code compiles:
The resulting output is:
drwxr-xr-x 17 root root 4.0KiB 08. May 2025 12:53 STA -- ( 0 D 0 F 0 EA 0BL) / drwxr-xr-x 18 root root 4.0KiB 27. Sep 2025 09:02 STA -- ( 0 D 0 F 0 EA 0BL) /mnt drwxr-xr-x 15 a a 4.0KiB 23. Mar 2025 10:41 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a drwx------ 18 a a 4.0KiB 01. Oct 2025 07:14 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev drwx------ 15 a a 4.0KiB 01. Oct 2025 08:22 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev/A-Worx drwxr-xr-x 10 a a 4.0KiB 01. Oct 2025 08:31 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev/A-Worx/ALib drwxr-xr-x 3 a a 4.0KiB 01. Oct 2025 08:10 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev/A-Worx/ALib/src drwxr-xr-x 26 a a 4.0KiB 01. Oct 2025 08:10 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev/A-Worx/ALib/src/alib drwxr-xr-x 3 a a 4.0KiB 01. Oct 2025 08:10 REC -- ( 1 D 1 F 0 EA 0BL) /mnt/a/dev/A-Worx/ALib/src/alib/files drwxr-xr-x 2 a a 4.0KiB 01. Oct 2025 08:10 REC -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev/A-Worx/ALib/src/alib/files/expressions -rw-r--r-- 1 a a 3.6KiB 01. Oct 2025 08:10 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev/A-Worx/ALib/src/alib/files/files.mpp
Here are some more samples:
drwxr-xr-x 17 root root 4.0KiB 08. May 2025 12:53 STA -- ( 0 D 0 F 0 EA 0BL) / drwxr-xr-x 18 root root 4.0KiB 27. Sep 2025 09:02 STA -- ( 0 D 0 F 0 EA 0BL) /mnt drwxr-xr-x 15 a a 4.0KiB 23. Mar 2025 10:41 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a drwx------ 18 a a 4.0KiB 01. Oct 2025 07:14 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev drwx------ 15 a a 4.0KiB 01. Oct 2025 08:22 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev/A-Worx drwxr-xr-x 10 a a 4.0KiB 01. Oct 2025 08:31 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev/A-Worx/ALib drwxr-xr-x 3 a a 4.0KiB 01. Oct 2025 08:10 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev/A-Worx/ALib/src drwxr-xr-x 26 a a 4.0KiB 01. Oct 2025 08:10 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev/A-Worx/ALib/src/alib drwxr-xr-x 3 a a 4.0KiB 01. Oct 2025 08:10 REC -- ( 1 D 8 F 0 EA 0BL) /mnt/a/dev/A-Worx/ALib/src/alib/files -rw-r--r-- 1 a a 69.1KiB 01. Oct 2025 08:10 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev/A-Worx/ALib/src/alib/files/fscanner.cpp drwxr-xr-x 2 a a 4.0KiB 01. Oct 2025 08:10 REC -- ( 0 D 2 F 0 EA 0BL) /mnt/a/dev/A-Worx/ALib/src/alib/files/expressions -rw-r--r-- 1 a a 13.2KiB 01. Oct 2025 08:10 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev/A-Worx/ALib/src/alib/files/expressions/fileexpressions.cpp -rw-r--r-- 1 a a 12.0KiB 01. Oct 2025 08:10 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev/A-Worx/ALib/src/alib/files/expressions/fileexpressions.inl -rw-r--r-- 1 a a 15.4KiB 01. Oct 2025 08:10 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev/A-Worx/ALib/src/alib/files/fscanner.inl -rw-r--r-- 1 a a 58.6KiB 01. Oct 2025 08:10 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev/A-Worx/ALib/src/alib/files/ftree.inl -rw-r--r-- 1 a a 18.4KiB 01. Oct 2025 08:10 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev/A-Worx/ALib/src/alib/files/file.cpp -rw-r--r-- 1 a a 36.3KiB 01. Oct 2025 08:10 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev/A-Worx/ALib/src/alib/files/finfo.inl -rw-r--r-- 1 a a 12.0KiB 01. Oct 2025 08:10 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev/A-Worx/ALib/src/alib/files/ftree.cpp
drwxr-xr-x 17 root root 4.0KiB 08. May 2025 12:53 STA -- ( 0 D 0 F 0 EA 0BL) / drwxr-xr-x 18 root root 4.0KiB 27. Sep 2025 09:02 STA -- ( 0 D 0 F 0 EA 0BL) /mnt drwxr-xr-x 15 a a 4.0KiB 23. Mar 2025 10:41 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a drwx------ 18 a a 4.0KiB 01. Oct 2025 07:14 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev drwx------ 15 a a 4.0KiB 01. Oct 2025 08:22 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev/A-Worx drwxr-xr-x 10 a a 4.0KiB 01. Oct 2025 08:31 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev/A-Worx/ALib drwxr-xr-x 3 a a 4.0KiB 01. Oct 2025 08:10 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev/A-Worx/ALib/src drwxr-xr-x 26 a a 4.0KiB 01. Oct 2025 08:10 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev/A-Worx/ALib/src/alib drwxr-xr-x 3 a a 4.0KiB 01. Oct 2025 08:10 REC -- ( 1 D 15 F 0 EA 0BL) /mnt/a/dev/A-Worx/ALib/src/alib/files -rw-r--r-- 1 a a 69.1KiB 01. Oct 2025 08:10 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev/A-Worx/ALib/src/alib/files/fscanner.cpp drwxr-xr-x 2 a a 4.0KiB 01. Oct 2025 08:10 REC -- ( 0 D 3 F 0 EA 0BL) /mnt/a/dev/A-Worx/ALib/src/alib/files/expressions -rw-r--r-- 1 a a 13.2KiB 01. Oct 2025 08:10 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev/A-Worx/ALib/src/alib/files/expressions/fileexpressions.cpp -rw-r--r-- 1 a a 12.0KiB 01. Oct 2025 08:10 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev/A-Worx/ALib/src/alib/files/expressions/fileexpressions.inl -rw-r--r-- 1 a a 2.9KiB 01. Oct 2025 08:10 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev/A-Worx/ALib/src/alib/files/expressions/fileexpressions.mpp -rw-r--r-- 1 a a 9.8KiB 01. Oct 2025 08:10 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev/A-Worx/ALib/src/alib/files/filescamp.cpp -rw-r--r-- 1 a a 15.4KiB 01. Oct 2025 08:10 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev/A-Worx/ALib/src/alib/files/fscanner.inl -rw-r--r-- 1 a a 58.6KiB 01. Oct 2025 08:10 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev/A-Worx/ALib/src/alib/files/ftree.inl -rw-r--r-- 1 a a 18.4KiB 01. Oct 2025 08:10 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev/A-Worx/ALib/src/alib/files/file.cpp -rw-r--r-- 1 a a 36.3KiB 01. Oct 2025 08:10 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev/A-Worx/ALib/src/alib/files/finfo.inl -rw-r--r-- 1 a a 3.6KiB 01. Oct 2025 08:10 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev/A-Worx/ALib/src/alib/files/files.mpp -rw-r--r-- 1 a a 1.7KiB 01. Oct 2025 08:10 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev/A-Worx/ALib/src/alib/files/files.prepro.hpp -rw-r--r-- 1 a a 3.9KiB 01. Oct 2025 08:10 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev/A-Worx/ALib/src/alib/files/finfo.cpp -rw-r--r-- 1 a a 12.0KiB 01. Oct 2025 08:10 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev/A-Worx/ALib/src/alib/files/ftree.cpp -rw-r--r-- 1 a a 1.9KiB 01. Oct 2025 08:10 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev/A-Worx/ALib/src/alib/files/filescamp.inl -rw-r--r-- 1 a a 2.7KiB 01. Oct 2025 08:10 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev/A-Worx/ALib/src/alib/files/ffilter.inl
drwxr-xr-x 17 root root 4.0KiB 08. May 2025 12:53 STA -- ( 0 D 0 F 0 EA 0BL) / drwxr-xr-x 18 root root 4.0KiB 27. Sep 2025 09:02 STA -- ( 0 D 0 F 0 EA 0BL) /mnt drwxr-xr-x 15 a a 4.0KiB 23. Mar 2025 10:41 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a drwx------ 18 a a 4.0KiB 01. Oct 2025 07:14 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev drwx------ 15 a a 4.0KiB 01. Oct 2025 08:22 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev/A-Worx drwxr-xr-x 10 a a 4.0KiB 01. Oct 2025 08:31 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev/A-Worx/ALib drwxr-xr-x 3 a a 4.0KiB 01. Oct 2025 08:10 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev/A-Worx/ALib/src drwxr-xr-x 26 a a 4.0KiB 01. Oct 2025 08:10 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev/A-Worx/ALib/src/alib drwxr-xr-x 3 a a 4.0KiB 01. Oct 2025 08:10 REC -- ( 1 D 2 F 0 EA 0BL) /mnt/a/dev/A-Worx/ALib/src/alib/files drwxr-xr-x 2 a a 4.0KiB 01. Oct 2025 08:10 REC -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev/A-Worx/ALib/src/alib/files/expressions -rw-r--r-- 1 a a 9.8KiB 01. Oct 2025 08:10 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev/A-Worx/ALib/src/alib/files/filescamp.cpp -rw-r--r-- 1 a a 1.9KiB 01. Oct 2025 08:10 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev/A-Worx/ALib/src/alib/files/filescamp.inl
drwxr-xr-x 17 root root 4.0KiB 08. May 2025 12:53 STA -- ( 0 D 0 F 0 EA 0BL) / drwxr-xr-x 18 root root 4.0KiB 27. Sep 2025 09:02 STA -- ( 0 D 0 F 0 EA 0BL) /mnt drwxr-xr-x 15 a a 4.0KiB 23. Mar 2025 10:41 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a drwx------ 18 a a 4.0KiB 01. Oct 2025 07:14 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev drwx------ 15 a a 4.0KiB 01. Oct 2025 08:22 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev/A-Worx drwxr-xr-x 10 a a 4.0KiB 01. Oct 2025 08:31 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev/A-Worx/ALib drwxr-xr-x 3 a a 4.0KiB 01. Oct 2025 08:10 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev/A-Worx/ALib/src drwxr-xr-x 26 a a 4.0KiB 01. Oct 2025 08:10 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev/A-Worx/ALib/src/alib drwxr-xr-x 3 a a 4.0KiB 01. Oct 2025 08:10 REC -- ( 1 D 12 F 0 EA 0BL) /mnt/a/dev/A-Worx/ALib/src/alib/files -rw-r--r-- 1 a a 69.1KiB 01. Oct 2025 08:10 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev/A-Worx/ALib/src/alib/files/fscanner.cpp drwxr-xr-x 2 a a 4.0KiB 01. Oct 2025 08:10 REC -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev/A-Worx/ALib/src/alib/files/expressions -rw-r--r-- 1 a a 9.8KiB 01. Oct 2025 08:10 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev/A-Worx/ALib/src/alib/files/filescamp.cpp -rw-r--r-- 1 a a 15.4KiB 01. Oct 2025 08:10 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev/A-Worx/ALib/src/alib/files/fscanner.inl -rw-r--r-- 1 a a 58.6KiB 01. Oct 2025 08:10 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev/A-Worx/ALib/src/alib/files/ftree.inl -rw-r--r-- 1 a a 18.4KiB 01. Oct 2025 08:10 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev/A-Worx/ALib/src/alib/files/file.cpp -rw-r--r-- 1 a a 36.3KiB 01. Oct 2025 08:10 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev/A-Worx/ALib/src/alib/files/finfo.inl -rw-r--r-- 1 a a 3.6KiB 01. Oct 2025 08:10 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev/A-Worx/ALib/src/alib/files/files.mpp -rw-r--r-- 1 a a 1.7KiB 01. Oct 2025 08:10 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev/A-Worx/ALib/src/alib/files/files.prepro.hpp -rw-r--r-- 1 a a 3.9KiB 01. Oct 2025 08:10 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev/A-Worx/ALib/src/alib/files/finfo.cpp -rw-r--r-- 1 a a 12.0KiB 01. Oct 2025 08:10 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev/A-Worx/ALib/src/alib/files/ftree.cpp -rw-r--r-- 1 a a 1.9KiB 01. Oct 2025 08:10 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev/A-Worx/ALib/src/alib/files/filescamp.inl -rw-r--r-- 1 a a 2.7KiB 01. Oct 2025 08:10 STA -- ( 0 D 0 F 0 EA 0BL) /mnt/a/dev/A-Worx/ALib/src/alib/files/ffilter.inl
Class FTree provides several interface methods that allow instances of abstract type FTreeListener to be registered for monitoring changes.
Those are:
For various reasons it is not - with reasonable effort and efficiency - possible to
trigger the notification events from inside class FTree automatically. Besides this class being just a rather thin layer on top of class StringTree, the class itself can never be sure when, for example, a new file entry is really finally created with all available information set.
For this reason, the notification events have to be triggered by the code entities that manipulate the tree. Notification is performed by callng method
with the according event type set.
Built-in scan functions duly perform such notifications. One warning has to be mentioned: If filter ScanParameters::DirectoryFilterPostRecursion is set, then notification about the creation of files, which later are removed by this filter will occur. On removal, only the node that is removed will be notified, but not the child nodes, which previously had been notified to having been created.
This is a design decision in favor to efficiency.
Class FTree allows attaching a custom object to each node. The memory of this custom object is allocated (and thus recycled with deletion of nodes) using the internal pool allocator.
It is up to the using software to keep track about which data type is assigned to which node of the tree. In the most common cases, where either all nodes receive the same data, or leaf-nodes (files) receive a different type than directories, this is no burden.
With debug-compilations, type information is stored with every node and it is asserted that the same type is received or deleted that was previously set.
The interface provided to manage custom data is comprised by the following methods:
Once this is done, methods of class File:
A convenience method is furthermore provided with:
However, this method is only applicable if all nodes have custom data of the same type set.
This should be enough for the time being. Module ALib Files is quite new and was introduced only with ALib C++ Library release Version 2402 and was extended and overhauled with Version 2412. The future will show how this module expands.
Again, consult the extensive Reference Documentation for all details about the currently existing functionality.