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. For example:

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 "scoped 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. See PathParser below:

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 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[] 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. Returns a reference to this class on success, or 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, and adopt the provided Path
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 #
Parse 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:
1
2
normal:  /x/y/z => /x/y
special: /x/y/  => /x
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?
PathParser parse(char[] path, size_t end) [package] #
Parse the path spec with explicit end point. A '\' is considered illegal in the path.
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 successfuy 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[] pop(char[] path) #
Returns a path representing the parent of this one, with a special case concerning a trailing '/':
1
2
3
normal:  /x/y/z => /x/y
special: /x/y/  => /x
final:   /x     => empty
char[] split(char[] path, out char[] head, out char[] tail) #
Break a path into "head" and "tail" components. For example:
1
2
"/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 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
1
2
. 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