tango.io.Path

Copyright:

Normalization & Patterns copyright (c) 2006-2009 Max Samukha, Thomas Kühne, Grzegorz Adam Hankiewicz

License:

BSD style: see license.txt

Version:

Mar 2008: Initial version
Oct 2009: Added PathUtil code

A more direct route to the file-system than FilePath. Use this if you don't need path editing features. For example, if all you want is to check some path exists, using this module would likely be more convenient than FilePath:

1
2
if (exists ("some/file/path"))
    ...

These functions may be less efficient than FilePath because they generally attach a null to the filename for each underlying O/S call. Use Path when you need pedestrian access to the file-system, and are not manipulating the path components. Use FilePath where path-editing or mutation is desired.

We encourage the use of "named import" with this module, such as:

1
2
3
4
import Path = tango.io.Path;

if (Path.exists ("some/file/path"))
    ...

Also residing here is a lightweight path-parser, which splits a filepath into constituent components. FilePath is based upon the same PathParser:

1
2
3
4
5
auto p = Path.parse ("some/file/path");
auto path = p.path;
auto name = p.name;
auto suffix = p.suffix;
...

Path normalization and pattern-matching is also hosted here via the normalize() and pattern() functions. See the doc towards the end of this module.

Compile with -version=Win32SansUnicode to enable Win95 & Win32s file support.

struct FS [package] #
Wraps the O/S specific calls with a D API. Note that these accept null-terminated strings only, which is why it's not public. We need this declared first to avoid forward-reference issues.
struct Stamps #
TimeStamp information. Accurate to whatever the F/S supports.
Time created #
Time created.
Time accessed #
Last time accessed.
Time modified #
Last time modified.
struct Listing #
Some fruct glue for directory listings.
void exception(char[] filename) [static] #
Throw an exception using the last known error.
void exception(char[] prefix, char[] error) [static] #
Throw an IO exception.
char[] padded(char[] path, char c = '/') [static] #
Return an adjusted path such that non-empty instances always have a trailing separator.

Note:

Allocates memory where path is not already terminated.
char[] paddedLeading(char[] path, char c = '/') [static] #
Return an adjusted path such that non-empty instances always have a leading separator.

Note:

Allocates memory where path is not already terminated.
char[] stripped(char[] path, char c = '/') [static] #
Return an adjusted path such that non-empty instances do not have a trailing separator.
char[] join(char[][] paths...) [static] #
Join a set of path specs together. A path separator is potentially inserted between each of the segments.

Note:

Allocates memory.
char[] strz(char[] src, char[] dst) [static] #
Append a terminating null onto a string, cheaply where feasible.

Note:

Allocates memory where the dst is too small.
wchar[] toString16(wchar[] tmp, char[] path) [private, static] #
Return a wchar[] instance of the path.
char[] toString(char[] tmp, wchar[] path) [private, static] #
Return a char[] instance of the path.
bool fileInfo(char[] name, ref WIN32_FILE_ATTRIBUTE_DATA info) [private, static] #
Get info about this path.
DWORD getInfo(char[] name, ref WIN32_FILE_ATTRIBUTE_DATA info) [private, static] #
Get info about this path.
DWORD getFlags(char[] name) [private, static] #
Get flags for this path.
bool exists(char[] name) [static] #
Return whether the file or path exists.
ulong fileSize(char[] name) [static] #
Return the file length (in bytes.)
bool isWritable(char[] name) [static] #
Is this file writable?
bool isFolder(char[] name) [static] #
Is this file actually a folder/directory?
bool isFile(char[] name) [static] #
Is this a normal file?
Stamps timeStamps(char[] name) [static] #
Return timestamp information.
Timestamps are returns in a format dictated by the file-system. For example NTFS keeps UTC time, while FAT timestamps are based on the local time.
void timeStamps(char[] name, Time accessed, Time modified) [static] #
Set the accessed and modified timestamps of the specified file.
void copy(char[] src, char[] dst) [static] #
Transfer the content of another file to this one. Throws an IOException upon failure.
bool remove(char[] name) [static] #
Remove the file/directory from the file-system. Returns true on success - false otherwise.
void rename(char[] src, char[] dst) [static] #
Change the name or location of a file/directory.
void createFile(char[] name) [static] #
Create a new file.
void createFolder(char[] name) [static] #
Create a new directory.
int list(char[] folder, int delegate(ref FileInfo) dg, bool all = false) [static] #
List the set of filenames within this folder.
Each path and filename is passed to the provided delegate, along with the path prefix and whether the entry is a folder or not.

Note:

Allocates a small memory buffer.
void createFile(char[] name, void delegate(HANDLE) dg) [private, static] #
Create a new file.
struct PathParser #
Parses a file path.
File paths containing non-ansi characters should be UTF-8 encoded. Supporting Unicode in this manner was deemed to be more suitable than providing a wchar version of PathParser, and is both consistent & compatible with the approach taken with the Uri class.

Note that patterns of adjacent '.' separators are treated specially in that they will be assigned to the name where there is no distinct suffix. In addition, a '.' at the start of a name signifies it does not belong to the suffix i.e. ".file" is a name rather than a suffix. Patterns of intermediate '.' characters will otherwise be assigned to the suffix, such that "file....suffix" includes the dots within the suffix itself. See method ext() for a suffix without dots.

Note also that normalization of path-separators does *not* occur by default. This means that usage of '\' characters should be explicitly converted beforehand into '/' instead (an exception is thrown in those cases where '\' is present). On-the-fly conversion is avoided because (a) the provided path is considered immutable and (b) we avoid taking a copy of the original path. Module FilePath exists at a higher level, without such contraints.

PathParser parse(char[] path) #
Parse the path spec.
PathParser dup() #
Duplicate this path.

Note:

Allocates memory for the path content.
char[] toString() #
Return the complete text of this filepath.
char[] root() #
Return the root of this path. Roots are constructs such as "C:".
char[] folder() #
Return the file path. Paths may start and end with a "/". The root path is "/" and an unspecified path is returned as an empty string. Directory paths may be split such that the directory name is placed into the 'name' member; directory paths are treated no differently than file paths.
char[] parent() #
Returns a path representing the parent of this one. This will typically return the current path component, though with a special case where the name component is empty. In such cases, the path is scanned for a prior segment:
  • normal: /x/y/z => /x/y
  • special: /x/y/ => /x
  • normal: /x => /
  • normal: / => [empty]
Note that this returns a path suitable for splitting into path and name components (there's no trailing separator).
char[] pop() #
Pop the rightmost element off this path, stripping off a trailing '/' as appropriate:
  • /x/y/z => /x/y
  • /x/y/ => /x/y (note trailing '/' in the original)
  • /x/y => /x
  • /x => /
  • / => [empty]
Note that this returns a path suitable for splitting into path and name components (there's no trailing separator).
char[] name() #
Return the name of this file, or directory.
char[] ext() #
Ext is the tail of the filename, rightward of the rightmost '.' separator e.g. path "foo.bar" has ext "bar". Note that patterns of adjacent separators are treated specially - for example, ".." will wind up with no ext at all.
char[] suffix() #
Suffix is like ext, but includes the separator e.g. path "foo.bar" has suffix ".bar".
char[] path() #
Return the root + folder combination.
char[] file() #
Return the name + suffix combination.
bool isAbsolute() #
Returns true if this path is *not* relative to the current working directory.
bool isEmpty() #
Returns true if this FilePath is empty.
bool isChild() #
Returns true if this path has a parent. Note that a parent is defined by the presence of a path-separator in the path. This means 'foo' within "/foo" is considered a child of the root.
int opEquals(char[] s) #
Does this path equate to the given text? We ignore trailing path-separators when testing equivalence.
PathParser parse(char[] path, size_t end) [package] #
Parse the path spec with explicit end point. A '\' is considered illegal in the path and should be normalized out before this is invoked (the content managed here is considered immutable, and thus cannot be changed by this function.)
bool exists(char[] name) #
Does this path currently exist?
Time modified(char[] name) #
Returns the time of the last modification. Accurate to whatever the F/S supports, and in a format dictated by the file-system. For example NTFS keeps UTC time, while FAT timestamps are based on the local time.
Time accessed(char[] name) #
Returns the time of the last access. Accurate to whatever the F/S supports, and in a format dictated by the file-system. For example NTFS keeps UTC time, while FAT timestamps are based on the local time.
Time created(char[] name) #
Returns the time of file creation. Accurate to whatever the F/S supports, and in a format dictated by the file-system. For example NTFS keeps UTC time, while FAT timestamps are based on the local time.
ulong fileSize(char[] name) #
Return the file length (in bytes.)
bool isWritable(char[] name) #
Is this file writable?
bool isFolder(char[] name) #
Is this file actually a folder/directory?
bool isFile(char[] name) #
Is this file actually a normal file? Not a directory or (on unix) a device file or link.
FS.Stamps timeStamps(char[] name) #
Return timestamp information.
Timestamps are returns in a format dictated by the file-system. For example NTFS keeps UTC time, while FAT timestamps are based on the local time.
void timeStamps(char[] name, Time accessed, Time modified) #
Set the accessed and modified timestamps of the specified file.

Since:

0.99.9
bool remove(char[] name) #
Remove the file/directory from the file-system. Returns true if successful, false otherwise.
char[][] remove(char[][] paths) #
Remove the files and folders listed in the provided paths. Where folders are listed, they should be preceded by their contained files in order to be successfully removed. Returns a set of paths that failed to be removed (where .length is zero upon success).
The collate() function can be used to provide the input paths:
1
remove (collate (".", "*.d", true));

Use with great caution.

Note:

May allocate memory.

Since:

0.99.9
void createFile(char[] name) #
Create a new file.
void createFolder(char[] name) #
Create a new directory.
void createPath(char[] path) #
Create an entire path consisting of this folder along with all parent folders. The path should not contain '.' or '..' segments, which can be removed via the normalize() function.
Note that each segment is created as a folder, including the trailing segment.

Throws:

IOException upon system errors.

Throws:

IllegalArgumentException if a segment exists but as a file instead of a folder.
void rename(char[] src, char[] dst) #
Change the name or location of a file/directory.
void copy(char[] src, char[] dst) #
Transfer the content of one file to another. Throws an IOException upon failure.
FS.Listing children(char[] path, bool all = false) #
Provides foreach support via a fruct, as in
1
2
foreach (info; children("myfolder"))
    ...
Each path and filename is passed to the foreach delegate, along with the path prefix and whether the entry is a folder or not. The info construct exposes the following attributes:
1
2
3
4
char[]  path
char[]  name
ulong   bytes
bool    folder

Argument 'all' controls whether hidden and system files are included - these are ignored by default.

char[][] collate(char[] path, char[] pattern, bool recurse = false) #
Collate all files and folders from the given path whose name matches the given pattern. Folders will be traversed where recurse is enabled, and a set of matching names is returned as filepaths (including those folders which match the pattern.)

Note:

Allocates memory for returned paths.

Since:

0.99.9
char[] join(char[][] paths...) #
Join a set of path specs together. A path separator is potentially inserted between each of the segments.

Note:

May allocate memory.
char[] standard(char[] path) #
Convert path separators to a standard format, using '/' as the path separator. This is compatible with Uri and all of the contemporary O/S which Tango supports. Known exceptions include the Windows command-line processor, which considers '/' characters to be switches instead. Use the native() method to support that.

Note:

Mutates the provided path.
char[] native(char[] path) #
Convert to native O/S path separators where that is required, such as when dealing with the Windows command-line.

Note:

Mutates the provided path. Use this pattern to obtain a copy instead: native(path.dup);
char[] parent(char[] path) #
Returns a path representing the parent of this one, with a special case concerning a trailing '/':
  • normal: /x/y/z => /x/y
  • normal: /x/y/ => /x/y
  • special: /x/y/ => /x
  • normal: /x => /
  • normal: / => empty
The result can be split via parse().
char[] pop(char[] path) #
Returns a path representing the parent of this one:
  • normal: /x/y/z => /x/y
  • normal: /x/y/ => /x/y
  • normal: /x => /
  • normal: / => empty
The result can be split via parse().
char[] split(char[] path, out char[] head, out char[] tail) #
Break a path into "head" and "tail" components. For example:
  • "/a/b/c" -> "/a","b/c"
  • "a/b/c" -> "a","b/c"
char[] replace(char[] path, char from, char to) #
Replace all path 'from' instances with 'to', in place (overwrites the provided path).
PathParser parse(char[] path) #
Parse a path into its constituent components.
Note that the provided path is sliced, not duplicated.
bool patternMatch(char[] filename, char[] pattern) #
Matches a pattern against a filename.
Some characters of pattern have special a meaning (they are meta-characters) and can't be escaped. These are:

* Matches 0 or more instances of any character.
? Matches exactly one instances 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.

Internally individual character comparisons are done calling charMatch(), so its rules apply here too. Note that path separators and dots don't stop a meta-character from matching further portions of the filename.

Returns:

true if pattern matches filename, false otherwise.

Throws:

Nothing.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
version (Win32)
{
  patternMatch("foo.bar", "*"); // => true
  patternMatch(r"foo/foo\bar", "f*b*r"); // => true
  patternMatch("foo.bar", "f?bar"); // => false
  patternMatch("Goo.bar", "[fg]???bar"); // => true
  patternMatch(r"d:\foo\bar", "d*foo?bar"); // => true
}
version (Posix)
{
  patternMatch("Go*.bar", "[fg]???bar"); // => false
  patternMatch("/foo*home/bar", "?foo*bar"); // => true
  patternMatch("foobar", "foo?bar"); // => true
}
char[] normalize(char[] path, char[] buf = null) #
Normalizes a path component.
  • . segments are removed
  • <segment>/.. are removed
Multiple consecutive forward slashes are replaced with a single forward slash. On Windows, \ will be converted to / prior to any normalization.

Note that any number of .. segments at the front is ignored, unless it is an absolute path, in which case they are removed.

The input path is copied into either the provided buffer, or a heap allocated array if no buffer was provided. Normalization modifies this copy before returning the relevant slice.

1
normalize("/home/foo/./bar/../../john/doe"); // => "/home/john/doe"

Note:

Allocates memory.