dirEntries

Returns an input range of DirEntry that lazily iterates a given directory, also provides two ways of foreach iteration. The iteration variable can be of type string if only the name is needed, or DirEntry if additional details are needed. The span mode dictates how the directory is traversed. The name of each iterated directory entry contains the absolute or relative path (depending on _pathname).

Note: The order of returned directory entries is as it is provided by the operating system / filesystem, and may not follow any particular sorting.

  1. auto dirEntries(string path, SpanMode mode, bool followSymlink)
  2. auto dirEntries(string path, string pattern, SpanMode mode, bool followSymlink)
    dirEntries
    (
    bool useDIP1000 = dip1000Enabled
    )
    (
    string path
    ,
    string pattern
    ,,
    bool followSymlink = true
    )

Parameters

useDIP1000

used to instantiate this function separately for code with and without -preview=dip1000 compiler switch, because it affects the ABI of this function. Set automatically - don't touch.

path string

The directory to iterate over. If empty, the current directory will be iterated.

pattern string

Optional string with wildcards, such as "*.d". When present, it is used to filter the results by their file name. The supported wildcard strings are described under std._path.globMatch.

mode SpanMode

Whether the directory's sub-directories should be iterated in depth-first post-order (depth), depth-first pre-order (breadth), or not at all (shallow).

Whether symbolic links which point to directories should be treated as directories and their contents iterated over.

Return Value

Type: auto

Throws

  • FileException if the path directory does not exist or read permission is denied.
  • FileException if mode is not shallow and a subdirectory cannot be read.

Examples

// Iterate a directory in depth
foreach (string name; dirEntries("destroy/me", SpanMode.depth))
{
    remove(name);
}

// Iterate the current directory in breadth
foreach (string name; dirEntries("", SpanMode.breadth))
{
    writeln(name);
}

// Iterate a directory and get detailed info about it
foreach (DirEntry e; dirEntries("dmd-testing", SpanMode.breadth))
{
    writeln(e.name, "\t", e.size);
}

// Iterate over all *.d files in current directory and all its subdirectories
auto dFiles = dirEntries("", SpanMode.depth).filter!(f => f.name.endsWith(".d"));
foreach (d; dFiles)
    writeln(d.name);

// Hook it up with std.parallelism to compile them all in parallel:
foreach (d; parallel(dFiles, 1)) //passes by 1 file to each thread
{
    string cmd = "dmd -c "  ~ d.name;
    writeln(cmd);
    std.process.executeShell(cmd);
}

// Iterate over all D source files in current directory and all its
// subdirectories
auto dFiles = dirEntries("","*.{d,di}",SpanMode.depth);
foreach (d; dFiles)
    writeln(d.name);

To handle subdirectories with denied read permission, use SpanMode.shallow:

void scan(string path)
{
    foreach (DirEntry entry; dirEntries(path, SpanMode.shallow))
    {
        try
        {
            writeln(entry.name);
            if (entry.isDir)
                scan(entry.name);
        }
        catch (FileException fe) { continue; } // ignore
    }
}

scan("");

Duplicate functionality of D1's std.file.listdir():

string[] listdir(string pathname)
{
    import std.algorithm.iteration : map, filter;
    import std.array : array;
    import std.path : baseName;

    return dirEntries(pathname, SpanMode.shallow)
        .filter!(a => a.isFile)
        .map!((return a) => baseName(a.name))
        .array;
}

// Can be safe only with -preview=dip1000
@safe void main(string[] args)
{
    import std.stdio : writefln;

    string[] files = listdir(args[1]);
    writefln("%s", files);
}

Meta