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 |
String used to separate directory names in a path. Under POSIX this is a slash, under Windows a backslash.
Path separator string. A colon under POSIX, a semicolon under Windows.
Determines whether the given character is a directory separator.
On Windows, this includes both \
and /
. On POSIX, it's just /
.
version (Windows) { assert( '/'.isDirSeparator); assert( '\\'.isDirSeparator); } else { assert( '/'.isDirSeparator); assert(!'\\'.isDirSeparator); }
This enum
is used as a template argument to functions which compare file names, and determines whether the comparison is case sensitive or not.
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`
File names are case insensitive
File names are case sensitive
The default (or most common) setting for the current platform. That is, no
on Windows and Mac OS X, and yes
on all POSIX systems except OS X (Linux, *BSD, etc.).
cs | Whether or not suffix matching is case-sensitive. |
R path
| A path name. It can be a string, or any random-access range of characters. |
C1[] suffix
| An optional suffix to be removed from the file name. |
suffix
is specified, it will be compared to path
using filenameCmp!cs
, where cs
is an optional template parameter determining whether the comparison is case sensitive or not. See the filenameCmp
documentation for details. stripExtension
. To obtain the filename without leading directories and without an extension, combine the functions like this: assert(baseName(stripExtension("dir/file.ext")) == "file");
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" }
Returns the parent directory of path. On Windows, this includes the drive letter if present.
R path
| A path name. |
path
or ".". 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` }
Returns the root directory of the specified path, or null
if the path is not rooted.
R path
| A path name. |
path
.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` }
Get the drive portion of a path.
R path
| string or range of characters |
path
that 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.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:"); }
Strips the drive from a Windows path. On POSIX, the path is returned unaltered.
R path
| A pathname |
version (Windows) { writeln(stripDrive(`d:\dir\file`)); // `\dir\file` writeln(stripDrive(`\\server\share\dir\file`)); // `\dir\file` }
R path
| A path name. |
null
is returned.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");
Remove extension from path.
R path
| string or range to be sliced |
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"
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 ext
is optional.
If the extension is empty, this function is equivalent to stripExtension
.
This function normally allocates a new string (the possible exception being the case when path is immutable and doesn't already have an extension).
C1[] path
| A path name |
C2[] ext
| The new extension |
path
, but where the extension has been set to ext
. withExtension
which does not allocate and returns a lazy range.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"
Replace existing extension on filespec with new one.
R path
| string or random access range representing a filespec |
C[] ext
| the new extension |
path
's extension (if any) replaced with ext
. The element encoding type of the returned range will be the same as path
's. setExtension
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
C1[] path
| A path name. |
C2[] ext
| The default extension to use. |
path
, with the extension given by ext
appended 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.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"
Set the extension of path
to ext
if path
doesn't have one.
R path
| filespec as string or range |
C[] ext
| extension, may have leading '.' |
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."
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 if paths
is a forward range.
Range segments
| An input range of segments to assemble the path from. |
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` }
Concatenate path segments together to form one path.
R1 r1
| first segment |
R2 r2
| second segment |
Ranges ranges
| 0 or more segments |
buildPath
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` }
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. Use asNormalizedPath
to not allocate memory.
const(C[])[] paths
| An array of paths to assemble. |
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`); }
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. Use buildNormalizedPath
to allocate memory and return a string.
R path
| string or random access range representing the path to normalize |
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`); }
Slice up a path into its elements.
R path
| string or slicable random access range |
path
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"])); }
Determines whether a path starts at a root directory.
R path
| A path name. |
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")); }
Determines whether a path is absolute or not.
R path
| A path name. |
_isAbsolute
is just an alias for isRooted
.) version (Posix) { assert(isAbsolute("/")); assert(isAbsolute("/foo")); assert(!isAbsolute("foo")); assert(!isAbsolute("../foo")); }On Windows, an absolute path starts at the root directory of a specific drive. Hence, it must start with
d:\
or d:/
, where d
is 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")); }
Transforms path
into an absolute path.
The following algorithm is used:
path
is empty, return null
.path
is already absolute, return it.path
to base
and return the result. If base
is not specified, the current working directory is used.string path
| the relative path to transform |
string base
| the base directory of the relative path |
Exception
if the specified base directory is not absolute. asAbsolutePath
which does not allocateversion (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` }
Transforms path
into an absolute path.
The following algorithm is used:
path
is empty, return null
.path
is already absolute, return it.path
to the current working directory, which allocates memory.R path
| the relative path to transform |
absolutePath
which returns an allocated stringimport 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");
Translates path
into a relative path.
The returned path is relative to base
, which is by default taken to be the current working directory. If specified, base
must be an absolute path, and it is always assumed to refer to a directory. If path
and base
refer to the same directory, the function returns .
.
The following algorithm is used:
path
is a relative directory, return it unaltered.path
and base
. If there is no common root, return path
unaltered.../
or ..\
as necessary to reach the common root from base path.path
to the string and return.filenameCmp!cs
, where cs
is an optional template parameter determining whether the comparison is case sensitive or not. See the filenameCmp
documentation for details. cs | Whether matching path name components against the base path should be case-sensitive or not. |
string path
| A path name. |
string base
| The base path to construct the relative path from. |
asRelativePath
which does not allocate memory Exception
if the specified base directory is not absolute.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` }
Transforms path
into a path relative to base
.
The returned path is relative to base
, which is usually the current working directory. base
must be an absolute path, and it is always assumed to refer to a directory. If path
and base
refer to the same directory, the function returns '.'
.
The following algorithm is used:
path
is a relative directory, return it unaltered.path
and base
. If there is no common root, return path
unaltered.../
or ..\
as necessary to reach the common root from base path.path
to the string and return.filenameCmp!cs
, where cs
is an optional template parameter determining whether the comparison is case sensitive or not. See the filenameCmp
documentation for details. R1 path
| path to transform |
R2 base
| absolute path |
cs | whether filespec comparisons are sensitive or not; defaults to CaseSensitive.osDefault
|
relativePath
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);
Compares filename characters.
This function can perform a case-sensitive or a case-insensitive comparison. This is controlled through the cs
template parameter which, if not specified, is given by CaseSensitive
.osDefault
.
On Windows, the backslash and slash characters (\
and /
) are considered equal.
cs | Case-sensitivity of the comparison. |
dchar a
| A filename character. |
dchar b
| A filename character. |
< 0
if a < b
, 0
if a == b
, and > 0
if a > b
.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); }
Compares file names and returns
Individual characters are compared using filenameCharCmp!cs
, where cs
is an optional template parameter determining whether the comparison is case sensitive or not.
Treatment of invalid UTF encodings is implementation defined.
cs | case sensitivity |
Range1 filename1
| range for first file name |
Range2 filename2
| range for second file name |
< 0
if filename1 < filename2
, 0
if filename1 == filename2
and > 0
if filename1 > filename2
. filenameCharCmp
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); }
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. |
filenameCharCmp!cs
, where cs
is an optional template parameter determining whether the comparison is case sensitive or not. See the filenameCharCmp
documentation for details. cs | Whether the matching should be case-sensitive |
Range path
| The path to be matched against |
const(C)[] pattern
| The glob pattern |
true
if pattern matches path, false
otherwise. 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")); }
Checks that the given file or directory name is valid.
The maximum length of filename
is given by the constant core.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 when filename
is a string of wchar
s.)
On Windows, the following criteria must be satisfied (source):
filename
must not contain any characters whose integer representation is in the range 0-31.filename
must not contain any of the following reserved characters: <>:"/\|?*filename
may not end with a space (' '
) or a period ('.'
).filename
may not contain a forward slash ('/'
) or the null character ('\0'
). Range filename
| string to check |
true
if and only if filename
is not empty, not too long, and does not contain invalid characters.import std.utf : byCodeUnit; assert(isValidFilename("hello.exe".byCodeUnit));
Checks whether path
is a valid path.
Generally, this function checks that path
is not empty, and that each component of the path either satisfies isValidFilename
or is equal to "."
or ".."
.
It does not check whether the path points to an existing file or directory; use std.file.exists
for this purpose.
On Windows, some special rules apply:
path
is a colon (':'
), the first character is interpreted as a drive letter, and must be in the range A-Z (case insensitive).path
is on the form \\server\share\...
(UNC path), isValidFilename
is applied to server and share as well.path
starts with \\?\
(long UNC path), the only requirement for the rest of the string is that it does not contain the null character.path
starts with \\.\
(Win32 device namespace) this function returns false
; such paths are beyond the scope of this module.Range path
| string or Range of characters to check |
path
is a valid path.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));
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/passwd
on 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 ~user
syntax 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.
string inputPath
| The path name to expand. |
inputPath
with the tilde expanded, or just inputPath
if it could not be expanded. For Windows, expandTilde
merely returns its argument inputPath
. void processFile(string path) { // Allow calling this function with paths such as ~/foo auto fullPath = expandTilde(path); ... }
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–2018 The D Language Foundation
Licensed under the Boost License 1.0.
https://dlang.org/phobos/std_path.html