Supports a model a bit like CSS selectors, where a selection
of operands is made before applying some operation. For example:
// count of files in this folder
auto count = folder.self.files;
// accumulated file byte-count
auto bytes = folder.self.bytes;
// a group of one folder (itself)
auto folders = folder.self;
The same approach is used to select the subtree descending from
a folder:
// count of files in this tree
auto count = folder.tree.files;
// accumulated file byte-count
auto bytes = folder.tree.bytes;
// the group of child folders
auto folders = folder.tree;
Filtering can be applied to the tree resulting in a sub-group.
Group operations remain applicable. Note that various wildcard
characters may be used in the filtering:
// select a subset of the resultant tree
auto folders = folder.tree.subset("install");
// get total file bytes for a tree subset, using wildcards
auto bytes = folder.tree.subset("foo*").bytes;
Files are selected from a set of folders in a similar manner:
// files called "readme.txt" in this folder
auto count = folder.self.catalog("readme.txt").files;
// files called "read*.*" in this tree
auto count = folder.tree.catalog("read*.*").files;
// all txt files belonging to folders starting with "ins"
auto count = folder.tree.subset("ins*").catalog("*.txt").files;
// custom-filtered files within a subtree
auto count = folder.tree.catalog(&filter).files;
Sets of folders and files support iteration via foreach:
foreach (folder; root.tree)
Stdout.formatln ("folder name:{}", folder.name);
foreach (folder; root.tree.subset("ins*"))
Stdout.formatln ("folder name:{}", folder.name);
foreach (file; root.tree.catalog("*.d"))
Stdout.formatln ("file name:{}", file.name);
Creating and opening a sub-folder is supported in a similar
manner, where the single instance is 'selected' before the
operation is applied. Open differs from create in that the
folder must exist for the former:
root.folder("myNewFolder").create;
root.folder("myExistingFolder").open;
File manipulation is handled in much the same way:
root.file("myNewFile").create;
auto source = root.file("myExistingFile");
root.file("myCopiedFile").copy(source);
The principal benefits of these approaches are twofold: 1) it
turns out to be notably more efficient in terms of traversal, and
2) there's no casting required, since there is a clean separation
between files and folders.
See VfsFile for more information on file handling
- abstract @property const(char)[] name();
- Return a short name
- abstract string toString();
- Return a long name
- abstract @property VfsFile file(const(char)[] path);
- Return a contained file representation
- abstract @property VfsFolderEntry folder(const(char)[] path);
- Return a contained folder representation
- abstract @property VfsFolders self();
- Returns a folder set containing only this one. Statistics
are inclusive of entries within this folder only
- abstract @property VfsFolders tree();
- Returns a subtree of folders. Statistics are inclusive of
files within this folder and all others within the tree
- abstract int opApply(scope int delegate(ref VfsFolder) dg);
- Iterate over the set of immediate child folders. This is
useful for reflecting the hierarchy
- abstract VfsFolder clear();
- Clear all content from this folder and subordinates
- abstract @property bool writable();
- Is folder writable?
- abstract VfsFolder close(bool commit = true);
- Close and/or synchronize changes made to this folder. Each
driver should take advantage of this as appropriate, perhaps
combining multiple files together, or possibly copying to a
remote location
- abstract void verify(VfsFolder folder, bool mounting);
- A folder is being added or removed from the hierarchy. Use
this to test for validity (or whatever) and throw exceptions
as necessary