On this page
std.path
This module is used to manipulate path strings.
All functions, with the exception of expandTilde (and in some cases absolutePath and relativePath), are pure string manipulation functions; they don't depend on any state outside the program, nor do they perform any actual file system actions. This has the consequence that the module does not make any distinction between a path that points to a directory and a path that points to a file, and it does not know whether or not the object pointed to by the path actually exists in the file system. To differentiate between these cases, use std.file.isDir and std.file.exists.
Note that on Windows, both the backslash (\) and the slash (/) are in principle valid directory separators. This module treats them both on equal footing, but in cases where a new separator is added, a backslash will be used. Furthermore, the buildNormalizedPath function will replace all slashes with backslashes on that platform.
In general, the functions in this module assume that the input paths are well-formed. (That is, they should not contain invalid characters, they should follow the file system's path format, etc.) The result of calling a function on an ill-formed path is undefined. When there is a chance that a path or a file name is invalid (for instance, when it has been input by the user), it may sometimes be desirable to use the isValidFilename and isValidPath functions to check this.
Most functions do not perform any memory allocations, and if a string is returned, it is usually a slice of an input string. If a function allocates, this is explicitly mentioned in the documentation.
| Category | Functions |
|---|---|
| Normalization | absolutePath asAbsolutePath asNormalizedPath asRelativePath buildNormalizedPath buildPath chainPath expandTilde |
| Partitioning | baseName dirName dirSeparator driveName pathSeparator pathSplitter relativePath rootName stripDrive |
| Validation | isAbsolute isDirSeparator isRooted isValidFilename isValidPath |
| Extension | defaultExtension extension setExtension stripExtension withDefaultExtension withExtension |
| Other | filenameCharCmp filenameCmp globMatch CaseSensitive |
- Authors:
- Lars Tandle Kyllingstad, Walter Bright, Grzegorz Adam Hankiewicz, Thomas Kühne, Andrei Alexandrescu
- License:
- Boost License 1.0
- Source
- std/path.d
- enum string dirSeparator;
-
String used to separate directory names in a path. Under POSIX this is a slash, under Windows a backslash.
- enum string pathSeparator;
-
Path separator string. A colon under POSIX, a semicolon under Windows.
- pure nothrow @nogc @safe bool isDirSeparator(dchar c);
-
Determines whether the given character is a directory separator.
On Windows, this includes both
\and/. On POSIX, it's just/.- Examples:
-
version (Windows) { assert( '/'.isDirSeparator); assert( '\\'.isDirSeparator); } else { assert( '/'.isDirSeparator); assert(!'\\'.isDirSeparator); }
- enum CaseSensitive: bool;
-
This
enumis used as a template argument to functions which compare file names, and determines whether the comparison is case sensitive or not.- Examples:
-
writeln(baseName!(CaseSensitive.no)("dir/file.EXT", ".ext")); // "file" assert(baseName!(CaseSensitive.yes)("dir/file.EXT", ".ext") != "file"); version (Posix) writeln(relativePath!(CaseSensitive.no)("/FOO/bar", "/foo/baz")); // "../bar" else writeln(relativePath!(CaseSensitive.no)(`c:\FOO\bar`, `c:\foo\baz`)); // `..\bar`
- no
-
File names are case insensitive
- yes
-
File names are case sensitive
- osDefault
-
The default (or most common) setting for the current platform. That is,
noon Windows and Mac OS X, andyeson all POSIX systems except Darwin (Linux, *BSD, etc.).
-
auto baseName(R)(R path)
Constraints: if (isRandomAccessRange!R && hasSlicing!R && isSomeChar!(ElementType!R) && !isSomeString!R);
auto baseName(C)(C[] path)
Constraints: if (isSomeChar!C);
pure @safe inout(C)[] baseName(CaseSensitive cs = CaseSensitive.osDefault, C, C1)(inout(C)[] path, in C1[] suffix)
Constraints: if (isSomeChar!C && isSomeChar!C1); -
- Parameters:
-
cs Whether or not suffix matching is case-sensitive. R pathA path name. It can be a string, or any random-access range of characters. C1[] suffixAn optional suffix to be removed from the file name.
- Returns:
-
The name of the file in the path name, without any leading directory and with an optional suffix chopped off. If
suffixis specified, it will be compared topathusingfilenameCmp!cs, wherecsis an optional template parameter determining whether the comparison is case sensitive or not. See thefilenameCmpdocumentation for details.
- Note
-
This function only strips away the specified suffix, which doesn't necessarily have to represent an extension. To remove the extension from a path, regardless of what the extension is, use
stripExtension. To obtain the filename without leading directories and without an extension, combine the functions like this:
assert(baseName(stripExtension("dir/file.ext")) == "file");- Standards:
- This function complies with the POSIX requirements for the 'basename' shell utility (with suitable adaptations for Windows paths).
- Examples:
-
writeln(baseName("dir/file.ext")); // "file.ext" writeln(baseName("dir/file.ext", ".ext")); // "file" writeln(baseName("dir/file.ext", ".xyz")); // "file.ext" writeln(baseName("dir/filename", "name")); // "file" writeln(baseName("dir/subdir/")); // "subdir" version (Windows) { writeln(baseName(`d:file.ext`)); // "file.ext" writeln(baseName(`d:\dir\file.ext`)); // "file.ext" }
-
auto dirName(R)(R path)
Constraints: if (isRandomAccessRange!R && hasSlicing!R && hasLength!R && isSomeChar!(ElementType!R) && !isSomeString!R);
auto dirName(C)(C[] path)
Constraints: if (isSomeChar!C); -
Returns the parent directory of
path. On Windows, this includes the drive letter if present. Ifpathis a relative path and the parent directory is the current working directory, returns".".- Parameters:
-
R pathA path name.
- Returns:
-
A slice of
pathor".".
- Standards:
- This function complies with the POSIX requirements for the 'dirname' shell utility (with suitable adaptations for Windows paths).
- Examples:
-
writeln(dirName("")); // "." writeln(dirName("file"w)); // "." writeln(dirName("dir/"d)); // "." writeln(dirName("dir///")); // "." writeln(dirName("dir/file"w.dup)); // "dir" writeln(dirName("dir///file"d.dup)); // "dir" writeln(dirName("dir/subdir/")); // "dir" writeln(dirName("/dir/file"w)); // "/dir" writeln(dirName("/file"d)); // "/" writeln(dirName("/")); // "/" writeln(dirName("///")); // "/" version (Windows) { writeln(dirName(`dir\`)); // `.` writeln(dirName(`dir\\\`)); // `.` writeln(dirName(`dir\file`)); // `dir` writeln(dirName(`dir\\\file`)); // `dir` writeln(dirName(`dir\subdir\`)); // `dir` writeln(dirName(`\dir\file`)); // `\dir` writeln(dirName(`\file`)); // `\` writeln(dirName(`\`)); // `\` writeln(dirName(`\\\`)); // `\` writeln(dirName(`d:`)); // `d:` writeln(dirName(`d:file`)); // `d:` writeln(dirName(`d:\`)); // `d:\` writeln(dirName(`d:\file`)); // `d:\` writeln(dirName(`d:\dir\file`)); // `d:\dir` writeln(dirName(`\\server\share\dir\file`)); // `\\server\share\dir` writeln(dirName(`\\server\share\file`)); // `\\server\share` writeln(dirName(`\\server\share\`)); // `\\server\share` writeln(dirName(`\\server\share`)); // `\\server\share` }
-
auto rootName(R)(R path)
Constraints: if (isRandomAccessRange!R && hasSlicing!R && hasLength!R && isSomeChar!(ElementType!R) && !isSomeString!R);
auto rootName(C)(C[] path)
Constraints: if (isSomeChar!C); -
Returns the root directory of the specified path, or
nullif the path is not rooted.- Parameters:
-
R pathA path name.
- Returns:
-
A slice of
path.
- Examples:
-
assert(rootName("") is null); assert(rootName("foo") is null); writeln(rootName("/")); // "/" writeln(rootName("/foo/bar")); // "/" version (Windows) { assert(rootName("d:foo") is null); writeln(rootName(`d:\foo`)); // `d:\` writeln(rootName(`\\server\share\foo`)); // `\\server\share` writeln(rootName(`\\server\share`)); // `\\server\share` }
-
auto driveName(R)(R path)
Constraints: if (isRandomAccessRange!R && hasSlicing!R && hasLength!R && isSomeChar!(ElementType!R) && !isSomeString!R);
auto driveName(C)(C[] path)
Constraints: if (isSomeChar!C); -
Get the drive portion of a path.
- Parameters:
-
R pathstring or range of characters
- Returns:
-
A slice of
paththat is the drive, or an empty range if the drive is not specified. In the case of UNC paths, the network share is returned. Always returns an empty range on POSIX.
- Examples:
-
import std.range : empty; version (Posix) assert(driveName("c:/foo").empty); version (Windows) { assert(driveName(`dir\file`).empty); writeln(driveName(`d:file`)); // "d:" writeln(driveName(`d:\file`)); // "d:" writeln(driveName("d:")); // "d:" writeln(driveName(`\\server\share\file`)); // `\\server\share` writeln(driveName(`\\server\share\`)); // `\\server\share` writeln(driveName(`\\server\share`)); // `\\server\share` static assert(driveName(`d:\file`) == "d:"); }
-
auto stripDrive(R)(R path)
Constraints: if (isRandomAccessRange!R && hasSlicing!R && isSomeChar!(ElementType!R) && !isSomeString!R);
auto stripDrive(C)(C[] path)
Constraints: if (isSomeChar!C); -
Strips the drive from a Windows path. On POSIX, the path is returned unaltered.
- Parameters:
-
R pathA pathname
- Returns:
- A slice of path without the drive component.
- Examples:
-
version (Windows) { writeln(stripDrive(`d:\dir\file`)); // `\dir\file` writeln(stripDrive(`\\server\share\dir\file`)); // `\dir\file` }
-
auto extension(R)(R path)
Constraints: if (isRandomAccessRange!R && hasSlicing!R && isSomeChar!(ElementType!R) || is(StringTypeOf!R)); -
- Parameters:
-
R pathA path name.
- Returns:
-
The extension part of a file name, including the dot. If there is no extension,
nullis returned.
- Examples:
-
import std.range : empty; assert(extension("file").empty); writeln(extension("file.")); // "." writeln(extension("file.ext"w)); // ".ext" writeln(extension("file.ext1.ext2"d)); // ".ext2" assert(extension(".foo".dup).empty); writeln(extension(".foo.ext"w.dup)); // ".ext" static assert(extension("file").empty); static assert(extension("file.ext") == ".ext");
-
auto stripExtension(R)(R path)
Constraints: if (isRandomAccessRange!R && hasSlicing!R && hasLength!R && isSomeChar!(ElementType!R) && !isSomeString!R);
auto stripExtension(C)(C[] path)
Constraints: if (isSomeChar!C); -
Remove extension from path.
- Parameters:
-
R pathstring or range to be sliced
- Returns:
- slice of path with the extension (if any) stripped off
- Examples:
-
writeln(stripExtension("file")); // "file" writeln(stripExtension("file.ext")); // "file" writeln(stripExtension("file.ext1.ext2")); // "file.ext1" writeln(stripExtension("file.")); // "file" writeln(stripExtension(".file")); // ".file" writeln(stripExtension(".file.ext")); // ".file" writeln(stripExtension("dir/file.ext")); // "dir/file"
-
immutable(C1)[] setExtension(C1, C2)(in C1[] path, in C2[] ext)
Constraints: if (isSomeChar!C1 && !is(C1 == immutable) && is(immutable(C1) == immutable(C2)));
immutable(C1)[] setExtension(C1, C2)(immutable(C1)[] path, const(C2)[] ext)
Constraints: if (isSomeChar!C1 && is(immutable(C1) == immutable(C2))); -
Sets or replaces an extension.
If the filename already has an extension, it is replaced. If not, the extension is simply appended to the filename. Including a leading dot in
extis optional.
If the extension is empty, this function is equivalent tostripExtension.
This function normally allocates a new string (the possible exception being the case when path is immutable and doesn't already have an extension).- Parameters:
-
C1[] pathA path name C2[] extThe new extension
- Returns:
-
A string containing the path given by
path, but where the extension has been set toext.
- See Also:
withExtensionwhich does not allocate and returns a lazy range.
- Examples:
-
writeln(setExtension("file", "ext")); // "file.ext" writeln(setExtension("file"w, ".ext"w)); // "file.ext" writeln(setExtension("file."d, "ext"d)); // "file.ext" writeln(setExtension("file.", ".ext")); // "file.ext" writeln(setExtension("file.old"w, "new"w)); // "file.new" writeln(setExtension("file.old"d, ".new"d)); // "file.new"
-
auto withExtension(R, C)(R path, C[] ext)
Constraints: if (isRandomAccessRange!R && hasSlicing!R && hasLength!R && isSomeChar!(ElementType!R) && !isSomeString!R && isSomeChar!C);
auto withExtension(C1, C2)(C1[] path, C2[] ext)
Constraints: if (isSomeChar!C1 && isSomeChar!C2); -
Replace existing extension on filespec with new one.
- Parameters:
-
R pathstring or random access range representing a filespec C[] extthe new extension
- Returns:
-
Range with
path's extension (if any) replaced withext. The element encoding type of the returned range will be the same aspath's.
- See Also:
-
setExtension
- Examples:
-
import std.array; writeln(withExtension("file", "ext").array); // "file.ext" writeln(withExtension("file"w, ".ext"w).array); // "file.ext" writeln(withExtension("file.ext"w, ".").array); // "file." import std.utf : byChar, byWchar; writeln(withExtension("file".byChar, "ext").array); // "file.ext" writeln(withExtension("file"w.byWchar, ".ext"w).array); // "file.ext"w writeln(withExtension("file.ext"w.byWchar, ".").array); // "file."w
-
immutable(C1)[] defaultExtension(C1, C2)(in C1[] path, in C2[] ext)
Constraints: if (isSomeChar!C1 && is(immutable(C1) == immutable(C2))); -
- Parameters:
-
C1[] pathA path name. C2[] extThe default extension to use.
- Returns:
-
The path given by
path, with the extension given byextappended if the path doesn't already have one. Including the dot in the extension is optional. This function always allocates a new string, except in the case when path is immutable and already has an extension.
- Examples:
-
writeln(defaultExtension("file", "ext")); // "file.ext" writeln(defaultExtension("file", ".ext")); // "file.ext" writeln(defaultExtension("file.", "ext")); // "file." writeln(defaultExtension("file.old", "new")); // "file.old" writeln(defaultExtension("file.old", ".new")); // "file.old"
-
auto withDefaultExtension(R, C)(R path, C[] ext)
Constraints: if (isRandomAccessRange!R && hasSlicing!R && hasLength!R && isSomeChar!(ElementType!R) && !isSomeString!R && isSomeChar!C);
auto withDefaultExtension(C1, C2)(C1[] path, C2[] ext)
Constraints: if (isSomeChar!C1 && isSomeChar!C2); -
Set the extension of
pathtoextifpathdoesn't have one.- Parameters:
-
R pathfilespec as string or range C[] extextension, may have leading '.'
- Returns:
- range with the result
- Examples:
-
import std.array; writeln(withDefaultExtension("file", "ext").array); // "file.ext" writeln(withDefaultExtension("file"w, ".ext").array); // "file.ext"w writeln(withDefaultExtension("file.", "ext").array); // "file." writeln(withDefaultExtension("file", "").array); // "file." import std.utf : byChar, byWchar; writeln(withDefaultExtension("file".byChar, "ext").array); // "file.ext" writeln(withDefaultExtension("file"w.byWchar, ".ext").array); // "file.ext"w writeln(withDefaultExtension("file.".byChar, "ext"d).array); // "file." writeln(withDefaultExtension("file".byChar, "").array); // "file."
-
immutable(ElementEncodingType!(ElementType!Range))[] buildPath(Range)(Range segments)
Constraints: if (isInputRange!Range && !isInfinite!Range && isSomeString!(ElementType!Range));
pure nothrow @safe immutable(C)[] buildPath(C)(const(C)[][] paths...)
Constraints: if (isSomeChar!C); -
Combines one or more path segments.
This function takes a set of path segments, given as an input range of string elements or as a set of string arguments, and concatenates them with each other. Directory separators are inserted between segments if necessary. If any of the path segments are absolute (as defined by
isAbsolute), the preceding segments will be dropped.
On Windows, if one of the path segments are rooted, but not absolute (e.g.\foo), all preceding path segments down to the previous root will be dropped. (See below for an example.)
This function always allocates memory to hold the resulting path. The variadic overload is guaranteed to only perform a single allocation, as is the range version ifpathsis a forward range.- Parameters:
-
Range segmentsAn input range of segments to assemble the path from.
- Returns:
- The assembled path.
- Examples:
-
version (Posix) { writeln(buildPath("foo", "bar", "baz")); // "foo/bar/baz" writeln(buildPath("/foo/", "bar/baz")); // "/foo/bar/baz" writeln(buildPath("/foo", "/bar")); // "/bar" } version (Windows) { writeln(buildPath("foo", "bar", "baz")); // `foo\bar\baz` writeln(buildPath(`c:\foo`, `bar\baz`)); // `c:\foo\bar\baz` writeln(buildPath("foo", `d:\bar`)); // `d:\bar` writeln(buildPath("foo", `\bar`)); // `\bar` writeln(buildPath(`c:\foo`, `\bar`)); // `c:\bar` }
-
auto chainPath(R1, R2, Ranges...)(R1 r1, R2 r2, Ranges ranges)
Constraints: if ((isRandomAccessRange!R1 && hasSlicing!R1 && hasLength!R1 && isSomeChar!(ElementType!R1) || isNarrowString!R1 && !isConvertibleToString!R1) && (isRandomAccessRange!R2 && hasSlicing!R2 && hasLength!R2 && isSomeChar!(ElementType!R2) || isNarrowString!R2 && !isConvertibleToString!R2) && (Ranges.length == 0 || is(typeof(chainPath(r2, ranges))))); -
Concatenate path segments together to form one path.
- Parameters:
-
R1 r1first segment R2 r2second segment Ranges ranges0 or more segments
- Returns:
- Lazy range which is the concatenation of r1, r2 and ranges with path separators. The resulting element type is that of r1.
- See Also:
-
buildPath
- Examples:
-
import std.array; version (Posix) { writeln(chainPath("foo", "bar", "baz").array); // "foo/bar/baz" writeln(chainPath("/foo/", "bar/baz").array); // "/foo/bar/baz" writeln(chainPath("/foo", "/bar").array); // "/bar" } version (Windows) { writeln(chainPath("foo", "bar", "baz").array); // `foo\bar\baz` writeln(chainPath(`c:\foo`, `bar\baz`).array); // `c:\foo\bar\baz` writeln(chainPath("foo", `d:\bar`).array); // `d:\bar` writeln(chainPath("foo", `\bar`).array); // `\bar` writeln(chainPath(`c:\foo`, `\bar`).array); // `c:\bar` } import std.utf : byChar; version (Posix) { writeln(chainPath("foo", "bar", "baz").array); // "foo/bar/baz" writeln(chainPath("/foo/".byChar, "bar/baz").array); // "/foo/bar/baz" writeln(chainPath("/foo", "/bar".byChar).array); // "/bar" } version (Windows) { writeln(chainPath("foo", "bar", "baz").array); // `foo\bar\baz` writeln(chainPath(`c:\foo`.byChar, `bar\baz`).array); // `c:\foo\bar\baz` writeln(chainPath("foo", `d:\bar`).array); // `d:\bar` writeln(chainPath("foo", `\bar`.byChar).array); // `\bar` writeln(chainPath(`c:\foo`, `\bar`w).array); // `c:\bar` }
-
pure nothrow @safe immutable(C)[] buildNormalizedPath(C)(const(C[])[] paths...)
Constraints: if (isSomeChar!C); -
Performs the same task as
buildPath, while at the same time resolving current/parent directory symbols ("."and"..") and removing superfluous directory separators. It will return "." if the path leads to the starting directory. On Windows, slashes are replaced with backslashes.Using buildNormalizedPath on null paths will always return null.
Note that this function does not resolve symbolic links.
This function always allocates memory to hold the resulting path. UseasNormalizedPathto not allocate memory.- Parameters:
-
const(C[])[] pathsAn array of paths to assemble.
- Returns:
- The assembled path.
- Examples:
-
writeln(buildNormalizedPath("foo", "..")); // "." version (Posix) { writeln(buildNormalizedPath("/foo/./bar/..//baz/")); // "/foo/baz" writeln(buildNormalizedPath("../foo/.")); // "../foo" writeln(buildNormalizedPath("/foo", "bar/baz/")); // "/foo/bar/baz" writeln(buildNormalizedPath("/foo", "/bar/..", "baz")); // "/baz" writeln(buildNormalizedPath("foo/./bar", "../../", "../baz")); // "../baz" writeln(buildNormalizedPath("/foo/./bar", "../../baz")); // "/baz" } version (Windows) { writeln(buildNormalizedPath(`c:\foo\.\bar/..\\baz\`)); // `c:\foo\baz` writeln(buildNormalizedPath(`..\foo\.`)); // `..\foo` writeln(buildNormalizedPath(`c:\foo`, `bar\baz\`)); // `c:\foo\bar\baz` writeln(buildNormalizedPath(`c:\foo`, `bar/..`)); // `c:\foo` assert(buildNormalizedPath(`\\server\share\foo`, `..\bar`) == `\\server\share\bar`); }
-
auto asNormalizedPath(R)(R path)
Constraints: if (isSomeChar!(ElementEncodingType!R) && (isRandomAccessRange!R && hasSlicing!R && hasLength!R || isNarrowString!R) && !isConvertibleToString!R); -
Normalize a path by resolving current/parent directory symbols (
"."and"..") and removing superfluous directory separators. It will return "." if the path leads to the starting directory. On Windows, slashes are replaced with backslashes.Using asNormalizedPath on empty paths will always return an empty path.
Does not resolve symbolic links.
This function always allocates memory to hold the resulting path. UsebuildNormalizedPathto allocate memory and return a string.- Parameters:
-
R pathstring or random access range representing the path to normalize
- Returns:
- normalized path as a forward range
- Examples:
-
import std.array; writeln(asNormalizedPath("foo/..").array); // "." version (Posix) { writeln(asNormalizedPath("/foo/./bar/..//baz/").array); // "/foo/baz" writeln(asNormalizedPath("../foo/.").array); // "../foo" writeln(asNormalizedPath("/foo/bar/baz/").array); // "/foo/bar/baz" writeln(asNormalizedPath("/foo/./bar/../../baz").array); // "/baz" } version (Windows) { writeln(asNormalizedPath(`c:\foo\.\bar/..\\baz\`).array); // `c:\foo\baz` writeln(asNormalizedPath(`..\foo\.`).array); // `..\foo` writeln(asNormalizedPath(`c:\foo\bar\baz\`).array); // `c:\foo\bar\baz` writeln(asNormalizedPath(`c:\foo\bar/..`).array); // `c:\foo` assert(asNormalizedPath(`\\server\share\foo\..\bar`).array == `\\server\share\bar`); }
-
auto pathSplitter(R)(R path)
Constraints: if ((isRandomAccessRange!R && hasSlicing!R || isNarrowString!R) && !isConvertibleToString!R); -
Slice up a path into its elements.
- Parameters:
-
R pathstring or slicable random access range
- Returns:
-
bidirectional range of slices of
path
- Examples:
-
import std.algorithm.comparison : equal; import std.conv : to; assert(equal(pathSplitter("/"), ["/"])); assert(equal(pathSplitter("/foo/bar"), ["/", "foo", "bar"])); assert(equal(pathSplitter("foo/../bar//./"), ["foo", "..", "bar", "."])); version (Posix) { assert(equal(pathSplitter("//foo/bar"), ["/", "foo", "bar"])); } version (Windows) { assert(equal(pathSplitter(`foo\..\bar\/.\`), ["foo", "..", "bar", "."])); assert(equal(pathSplitter("c:"), ["c:"])); assert(equal(pathSplitter(`c:\foo\bar`), [`c:\`, "foo", "bar"])); assert(equal(pathSplitter(`c:foo\bar`), ["c:foo", "bar"])); }
-
bool isRooted(R)(R path)
Constraints: if (isRandomAccessRange!R && isSomeChar!(ElementType!R) || is(StringTypeOf!R)); -
Determines whether a path starts at a root directory.
- Parameters:
-
R pathA path name.
- Returns:
- Whether a path starts at a root directory. On POSIX, this function returns true if and only if the path starts with a slash (/). On Windows, this function returns true if the path starts at the root directory of the current drive, of some other drive, or of a network drive.
- Examples:
-
version (Posix) { assert( isRooted("/")); assert( isRooted("/foo")); assert(!isRooted("foo")); assert(!isRooted("../foo")); } version (Windows) { assert( isRooted(`\`)); assert( isRooted(`\foo`)); assert( isRooted(`d:\foo`)); assert( isRooted(`\\foo\bar`)); assert(!isRooted("foo")); assert(!isRooted("d:foo")); }
-
pure nothrow @safe bool isAbsolute(R)(R path)
Constraints: if (isRandomAccessRange!R && isSomeChar!(ElementType!R) || is(StringTypeOf!R)); -
Determines whether a path is absolute or not.
- Parameters:
-
R pathA path name.
- Returns:
- Whether a path is absolute or not.
- Example
-
On POSIX, an absolute path starts at the root directory. (In fact,
_isAbsoluteis just an alias forisRooted.)
On Windows, an absolute path starts at the root directory of a specific drive. Hence, it must start withversion (Posix) { assert(isAbsolute("/")); assert(isAbsolute("/foo")); assert(!isAbsolute("foo")); assert(!isAbsolute("../foo")); }d:\ord:/, wheredis the drive letter. Alternatively, it may be a network path, i.e. a path starting with a double (back)slash.version (Windows) { assert(isAbsolute(`d:\`)); assert(isAbsolute(`d:\foo`)); assert(isAbsolute(`\\foo\bar`)); assert(!isAbsolute(`\`)); assert(!isAbsolute(`\foo`)); assert(!isAbsolute("d:foo")); } - pure @safe string absolutePath(string path, lazy string base = getcwd());
-
Transforms
pathinto an absolute path.The following algorithm is used:
- If
pathis empty, returnnull. - If
pathis already absolute, return it. - Otherwise, append
pathtobaseand return the result. Ifbaseis not specified, the current working directory is used.
- Parameters:
-
string paththe relative path to transform string basethe base directory of the relative path
- Returns:
- string of transformed path
- Throws:
Exceptionif the specified base directory is not absolute.
- See Also:
asAbsolutePathwhich does not allocate
- Examples:
-
version (Posix) { writeln(absolutePath("some/file", "/foo/bar")); // "/foo/bar/some/file" writeln(absolutePath("../file", "/foo/bar")); // "/foo/bar/../file" writeln(absolutePath("/some/file", "/foo/bar")); // "/some/file" } version (Windows) { writeln(absolutePath(`some\file`, `c:\foo\bar`)); // `c:\foo\bar\some\file` writeln(absolutePath(`..\file`, `c:\foo\bar`)); // `c:\foo\bar\..\file` writeln(absolutePath(`c:\some\file`, `c:\foo\bar`)); // `c:\some\file` writeln(absolutePath(`\`, `c:\`)); // `c:\` writeln(absolutePath(`\some\file`, `c:\foo\bar`)); // `c:\some\file` }
- If
-
auto asAbsolutePath(R)(R path)
Constraints: if ((isRandomAccessRange!R && isSomeChar!(ElementType!R) || isNarrowString!R) && !isConvertibleToString!R); -
Transforms
pathinto an absolute path.The following algorithm is used:
- If
pathis empty, returnnull. - If
pathis already absolute, return it. - Otherwise, append
pathto the current working directory, which allocates memory.
- Parameters:
-
R paththe relative path to transform
- Returns:
- the transformed path as a lazy range
- See Also:
absolutePathwhich returns an allocated string
- Examples:
-
import std.array; writeln(asAbsolutePath(cast(string)null).array); // "" version (Posix) { writeln(asAbsolutePath("/foo").array); // "/foo" } version (Windows) { writeln(asAbsolutePath("c:/foo").array); // "c:/foo" } asAbsolutePath("foo");
- If
- string relativePath(CaseSensitive cs = CaseSensitive.osDefault)(string path, lazy string base = getcwd());
-
Translates
pathinto a relative path.The returned path is relative to
base, which is by default taken to be the current working directory. If specified,basemust be an absolute path, and it is always assumed to refer to a directory. Ifpathandbaserefer to the same directory, the function returns..
The following algorithm is used:- If
pathis a relative directory, return it unaltered. - Find a common root between
pathandbase. If there is no common root, returnpathunaltered. - Prepare a string with as many
../or..\as necessary to reach the common root from base path. - Append the remaining segments of
pathto the string and return.
In the second step, path components are compared usingfilenameCmp!cs, wherecsis an optional template parameter determining whether the comparison is case sensitive or not. See thefilenameCmpdocumentation for details.
This function allocates memory.- Parameters:
-
cs Whether matching path name components against the base path should be case-sensitive or not. string pathA path name. string baseThe base path to construct the relative path from.
- Returns:
- The relative path.
- See Also:
asRelativePathwhich does not allocate memory
- Throws:
Exceptionif the specified base directory is not absolute.
- Examples:
-
writeln(relativePath("foo")); // "foo" version (Posix) { writeln(relativePath("foo", "/bar")); // "foo" writeln(relativePath("/foo/bar", "/foo/bar")); // "." writeln(relativePath("/foo/bar", "/foo/baz")); // "../bar" writeln(relativePath("/foo/bar/baz", "/foo/woo/wee")); // "../../bar/baz" writeln(relativePath("/foo/bar/baz", "/foo/bar")); // "baz" } version (Windows) { writeln(relativePath("foo", `c:\bar`)); // "foo" writeln(relativePath(`c:\foo\bar`, `c:\foo\bar`)); // "." writeln(relativePath(`c:\foo\bar`, `c:\foo\baz`)); // `..\bar` writeln(relativePath(`c:\foo\bar\baz`, `c:\foo\woo\wee`)); // `..\..\bar\baz` writeln(relativePath(`c:\foo\bar\baz`, `c:\foo\bar`)); // "baz" writeln(relativePath(`c:\foo\bar`, `d:\foo`)); // `c:\foo\bar` }
- If
-
auto asRelativePath(CaseSensitive cs = CaseSensitive.osDefault, R1, R2)(R1 path, R2 base)
Constraints: if ((isNarrowString!R1 || isRandomAccessRange!R1 && hasSlicing!R1 && isSomeChar!(ElementType!R1) && !isConvertibleToString!R1) && (isNarrowString!R2 || isRandomAccessRange!R2 && hasSlicing!R2 && isSomeChar!(ElementType!R2) && !isConvertibleToString!R2)); -
Transforms
pathinto a path relative tobase.The returned path is relative to
base, which is usually the current working directory.basemust be an absolute path, and it is always assumed to refer to a directory. Ifpathandbaserefer to the same directory, the function returns'.'.
The following algorithm is used:- If
pathis a relative directory, return it unaltered. - Find a common root between
pathandbase. If there is no common root, returnpathunaltered. - Prepare a string with as many
../or..\as necessary to reach the common root from base path. - Append the remaining segments of
pathto the string and return.
In the second step, path components are compared usingfilenameCmp!cs, wherecsis an optional template parameter determining whether the comparison is case sensitive or not. See thefilenameCmpdocumentation for details.- Parameters:
-
R1 pathpath to transform R2 baseabsolute path cs whether filespec comparisons are sensitive or not; defaults to CaseSensitive.osDefault
- Returns:
- a random access range of the transformed path
- See Also:
-
relativePath
- Examples:
-
import std.array; version (Posix) { writeln(asRelativePath("foo", "/bar").array); // "foo" writeln(asRelativePath("/foo/bar", "/foo/bar").array); // "." writeln(asRelativePath("/foo/bar", "/foo/baz").array); // "../bar" writeln(asRelativePath("/foo/bar/baz", "/foo/woo/wee").array); // "../../bar/baz" writeln(asRelativePath("/foo/bar/baz", "/foo/bar").array); // "baz" } else version (Windows) { writeln(asRelativePath("foo", `c:\bar`).array); // "foo" writeln(asRelativePath(`c:\foo\bar`, `c:\foo\bar`).array); // "." writeln(asRelativePath(`c:\foo\bar`, `c:\foo\baz`).array); // `..\bar` writeln(asRelativePath(`c:\foo\bar\baz`, `c:\foo\woo\wee`).array); // `..\..\bar\baz` writeln(asRelativePath(`c:/foo/bar/baz`, `c:\foo\woo\wee`).array); // `..\..\bar\baz` writeln(asRelativePath(`c:\foo\bar\baz`, `c:\foo\bar`).array); // "baz" writeln(asRelativePath(`c:\foo\bar`, `d:\foo`).array); // `c:\foo\bar` writeln(asRelativePath(`\\foo\bar`, `c:\foo`).array); // `\\foo\bar` } else static assert(0);
- If
- pure nothrow @safe int filenameCharCmp(CaseSensitive cs = CaseSensitive.osDefault)(dchar a, dchar b);
-
Compares filename characters.
This function can perform a case-sensitive or a case-insensitive comparison. This is controlled through the
cstemplate parameter which, if not specified, is given byCaseSensitive.osDefault.
On Windows, the backslash and slash characters (\and/) are considered equal.- Parameters:
-
cs Case-sensitivity of the comparison. dchar aA filename character. dchar bA filename character.
- Returns:
< 0ifa < b,0ifa == b, and> 0ifa > b.
- Examples:
-
writeln(filenameCharCmp('a', 'a')); // 0 assert(filenameCharCmp('a', 'b') < 0); assert(filenameCharCmp('b', 'a') > 0); version (linux) { // Same as calling filenameCharCmp!(CaseSensitive.yes)(a, b) assert(filenameCharCmp('A', 'a') < 0); assert(filenameCharCmp('a', 'A') > 0); } version (Windows) { // Same as calling filenameCharCmp!(CaseSensitive.no)(a, b) writeln(filenameCharCmp('a', 'A')); // 0 assert(filenameCharCmp('a', 'B') < 0); assert(filenameCharCmp('A', 'b') < 0); }
-
int filenameCmp(CaseSensitive cs = CaseSensitive.osDefault, Range1, Range2)(Range1 filename1, Range2 filename2)
Constraints: if (isInputRange!Range1 && !isInfinite!Range1 && isSomeChar!(ElementEncodingType!Range1) && !isConvertibleToString!Range1 && isInputRange!Range2 && !isInfinite!Range2 && isSomeChar!(ElementEncodingType!Range2) && !isConvertibleToString!Range2); -
Compares file names and returns
Individual characters are compared using
filenameCharCmp!cs, wherecsis an optional template parameter determining whether the comparison is case sensitive or not.
Treatment of invalid UTF encodings is implementation defined.- Parameters:
-
cs case sensitivity Range1 filename1range for first file name Range2 filename2range for second file name
- Returns:
< 0iffilename1 < filename2,0iffilename1 == filename2and> 0iffilename1 > filename2.
- See Also:
-
filenameCharCmp
- Examples:
-
writeln(filenameCmp("abc", "abc")); // 0 assert(filenameCmp("abc", "abd") < 0); assert(filenameCmp("abc", "abb") > 0); assert(filenameCmp("abc", "abcd") < 0); assert(filenameCmp("abcd", "abc") > 0); version (linux) { // Same as calling filenameCmp!(CaseSensitive.yes)(filename1, filename2) assert(filenameCmp("Abc", "abc") < 0); assert(filenameCmp("abc", "Abc") > 0); } version (Windows) { // Same as calling filenameCmp!(CaseSensitive.no)(filename1, filename2) writeln(filenameCmp("Abc", "abc")); // 0 writeln(filenameCmp("abc", "Abc")); // 0 assert(filenameCmp("Abc", "abD") < 0); assert(filenameCmp("abc", "AbB") > 0); }
-
pure nothrow @safe bool globMatch(CaseSensitive cs = CaseSensitive.osDefault, C, Range)(Range path, const(C)[] pattern)
Constraints: if (isForwardRange!Range && !isInfinite!Range && isSomeChar!(ElementEncodingType!Range) && !isConvertibleToString!Range && isSomeChar!C && is(immutable(C) == immutable(ElementEncodingType!Range))); -
Matches a pattern against a path.
Some characters of pattern have a special meaning (they are meta-characters) and can't be escaped. These are:
*Matches 0 or more instances of any character. ?Matches exactly one instance of any character. [chars]Matches one instance of any character that appears between the brackets. [!chars]Matches one instance of any character that does not appear between the brackets after the exclamation mark. {string1,string2,…}Matches either of the specified strings.
Individual characters are compared usingfilenameCharCmp!cs, wherecsis an optional template parameter determining whether the comparison is case sensitive or not. See thefilenameCharCmpdocumentation for details.
Note that directory separators and dots don't stop a meta-character from matching further portions of the path.- Parameters:
-
cs Whether the matching should be case-sensitive Range pathThe path to be matched against const(C)[] patternThe glob pattern
- Returns:
trueif pattern matches path,falseotherwise.
- See Also:
- Wikipedia: glob (programming)
- Examples:
-
assert(globMatch("foo.bar", "*")); assert(globMatch("foo.bar", "*.*")); assert(globMatch(`foo/foo\bar`, "f*b*r")); assert(globMatch("foo.bar", "f???bar")); assert(globMatch("foo.bar", "[fg]???bar")); assert(globMatch("foo.bar", "[!gh]*bar")); assert(globMatch("bar.fooz", "bar.{foo,bif}z")); assert(globMatch("bar.bifz", "bar.{foo,bif}z")); version (Windows) { // Same as calling globMatch!(CaseSensitive.no)(path, pattern) assert(globMatch("foo", "Foo")); assert(globMatch("Goo.bar", "[fg]???bar")); } version (linux) { // Same as calling globMatch!(CaseSensitive.yes)(path, pattern) assert(!globMatch("foo", "Foo")); assert(!globMatch("Goo.bar", "[fg]???bar")); }
-
bool isValidFilename(Range)(Range filename)
Constraints: if ((isRandomAccessRange!Range && hasLength!Range && hasSlicing!Range && isSomeChar!(ElementEncodingType!Range) || isNarrowString!Range) && !isConvertibleToString!Range); -
Checks that the given file or directory name is valid.
The maximum length of
filenameis given by the constantcore.stdc.stdio.FILENAME_MAX. (On Windows, this number is defined as the maximum number of UTF-16 code points, and the test will therefore only yield strictly correct results whenfilenameis a string ofwchars.)
On Windows, the following criteria must be satisfied (source):filenamemust not contain any characters whose integer representation is in the range 0-31.filenamemust not contain any of the following reserved characters:<>:"/\|?*filenamemay not end with a space (' ') or a period ('.').
On POSIX,filenamemay not contain a forward slash ('/') or the null character ('\0').- Parameters:
-
Range filenamestring to check
- Returns:
trueif and only iffilenameis not empty, not too long, and does not contain invalid characters.
- Examples:
-
import std.utf : byCodeUnit; assert(isValidFilename("hello.exe".byCodeUnit));
-
bool isValidPath(Range)(Range path)
Constraints: if ((isRandomAccessRange!Range && hasLength!Range && hasSlicing!Range && isSomeChar!(ElementEncodingType!Range) || isNarrowString!Range) && !isConvertibleToString!Range); -
Checks whether
pathis a valid path.Generally, this function checks that
pathis not empty, and that each component of the path either satisfiesisValidFilenameor is equal to"."or"..".
It does not check whether the path points to an existing file or directory; usestd.file.existsfor this purpose.
On Windows, some special rules apply:- If the second character of
pathis a colon (':'), the first character is interpreted as a drive letter, and must be in the range A-Z (case insensitive). - If
pathis on the form\\server\share\...(UNC path),isValidFilenameis applied to server and share as well. - If
pathstarts with\\?\(long UNC path), the only requirement for the rest of the string is that it does not contain the null character. - If
pathstarts with\\.\(Win32 device namespace) this function returnsfalse; such paths are beyond the scope of this module.
- Parameters:
-
Range pathstring or Range of characters to check
- Returns:
-
true if
pathis a valid path.
- Examples:
-
assert(isValidPath("/foo/bar")); assert(!isValidPath("/foo\0/bar")); assert(isValidPath("/")); assert(isValidPath("a")); version (Windows) { assert(isValidPath(`c:\`)); assert(isValidPath(`c:\foo`)); assert(isValidPath(`c:\foo\.\bar\\\..\`)); assert(!isValidPath(`!:\foo`)); assert(!isValidPath(`c::\foo`)); assert(!isValidPath(`c:\foo?`)); assert(!isValidPath(`c:\foo.`)); assert(isValidPath(`\\server\share`)); assert(isValidPath(`\\server\share\foo`)); assert(isValidPath(`\\server\share\\foo`)); assert(!isValidPath(`\\\server\share\foo`)); assert(!isValidPath(`\\server\\share\foo`)); assert(!isValidPath(`\\ser*er\share\foo`)); assert(!isValidPath(`\\server\sha?e\foo`)); assert(!isValidPath(`\\server\share\|oo`)); assert(isValidPath(`\\?\<>:"?*|/\..\.`)); assert(!isValidPath("\\\\?\\foo\0bar")); assert(!isValidPath(`\\.\PhysicalDisk1`)); assert(!isValidPath(`\\`)); } import std.utf : byCodeUnit; assert(isValidPath("/foo/bar".byCodeUnit));
- If the second character of
- nothrow @safe string expandTilde(string inputPath);
-
Performs tilde expansion in paths on POSIX systems. On Windows, this function does nothing.
There are two ways of using tilde expansion in a path. One involves using the tilde alone or followed by a path separator. In this case, the tilde will be expanded with the value of the environment variable
HOME. The second way is putting a username after the tilde (i.e.~john/Mail). Here, the username will be searched for in the user database (i.e./etc/passwdon Unix systems) and will expand to whatever path is stored there. The username is considered the string after the tilde ending at the first instance of a path separator.
Note that using the~usersyntax may give different values from just~if the environment variable doesn't match the value stored in the user database.
When the environment variable version is used, the path won't be modified if the environment variable doesn't exist or it is empty. When the database version is used, the path won't be modified if the user doesn't exist in the database or there is not enough memory to perform the query.
This function performs several memory allocations.- Parameters:
-
string inputPathThe path name to expand.
- Returns:
inputPathwith the tilde expanded, or justinputPathif it could not be expanded. For Windows,expandTildemerely returns its argumentinputPath.
- Example
void processFile(string path) { // Allow calling this function with paths such as ~/foo auto fullPath = expandTilde(path); ... }- Examples:
-
version (Posix) { import std.process : environment; auto oldHome = environment["HOME"]; scope(exit) environment["HOME"] = oldHome; environment["HOME"] = "dmd/test"; writeln(expandTilde("~/")); // "dmd/test/" writeln(expandTilde("~")); // "dmd/test" }
© 1999–2021 The D Language Foundation
Licensed under the Boost License 1.0.
https://dlang.org/phobos/std_path.html