FileSystem
FileSystem is a filesystem interface.
You can access the native filesystem by calling FileSystem::native().
A FileSystem object expects either Windows paths or POSIX-style paths, depending on its
implementation. The NativePath class always manipulate paths in the appropriate format for the
native filesystem. When working with an abstract FileSystem where the path format is unknown,
pathFormat() will return a PathFormat object suitable for manipulating paths in the expected
format. See Manipulating Paths for more information.
You can create a virtual filesystem by calling createVirtual(), or even implement your own.
Virtual filesystems don't necessarily support all the member functions in the FileSystem
interface.
Result Codes
Most FileSystem member functions update an internal result code. This result code is stored in a
thread-local variable of type FSResult. Some member functions, such as makeDir(), return the
result code explicitly. Other member functions, such as loadTextAutodetect(), do not return the
result code explicitly. You can always access the last result code by calling lastResult().
Note that, because the internal result code is thread-local, it's shared across all FileSystem
instances. For example, an operation on a virtual filesystem will update the result code for the
native filesystem, and vice versa.
In some cases, a function may set the result code to Unknown instead of one of the result codes
documented here. Such cases mean that Plywood needs to be updated to recognize the underlying error.
Header File
#include <ply-runtime/filesystem/FileSystem.h>
Also included from <ply-runtime/Base.h>.
Member Functions
-
Returns a
FileSystemobject that interacts with the native filesystem. -
Returns a
PathFormatdescribing the filesystem's expected path format. This object can be used to manipulate paths in the expected format. -
Sets the working directory of the process in the target filesystem. May not be supported in virtual filesystems.
This function updates the internal result code. The result code is also returned directly. Expected result codes are
OKorNotFound. -
Gets the working directory of the process in the target filesystem.
This function updates the internal result code. The expected result code is
OK. -
Returns the last result code.
-
Sets the last result code.
-
Checks whether a file or directory with the specified pathname exists. The return value is one of
File,DirectoryorNotFound.This function does not update the internal result code.
-
Returns
trueifpathspecifies the name of a directory. Shorthand forexists(path) == ExistsResult::Directory.This function does not update the internal result code.
-
Returns a
Directoryobject. TheDirectoryobject can be used in a range-based for loop to enumerate the contents of a directory. Such a range-based for loop iterates over a sequence ofDirectoryEntryobjects. It is recommended to iterate by reference in order to avoid copying theDirectoryEntryobject. EachDirectoryEntrytakes the following form:struct DirectoryEntry { String name; bool isDir; u64 fileSize; // Only valid if WithSizes was specified double creationTime; // Only valid if WithTimes was specified double accessTime; double modificationTime; };The entries are returned in an arbitrary order, and the special directory entries
"."and".."are not enumerated.The
flagsargument accepts a bitwise-or of zero or more of the following values:FileSystem::WithSizesFileSystem::WithFlags
The
fileSizemember ofDirectoryEntryis only valid ifWithSizeswas set. ThecreationTime,accessTimeandmodificationTimemembers are only valid ifWithTimeswas set. Using these flags is likely faster than callinggetFileStatus()on the individual files, especially on Windows. Conversely, if the additional information is not needed, it might be faster to omit these flags on some platforms.The following example outputs a list of non-directory files in the current directory:
OutStream outs = StdOut::text(); for (const DirectoryEntry& entry : FileSystem::native()->listDir(".", 0)) { if (!entry.isDir) { outs << entry.name << '\n'; } }The initial call to
listDir()updates the internal result code. Expected result codes areOK,NotFoundorAccessDenied. Each iteration of the loop updates the internal result code as well. Expected result codes areOKorNotFound(if, for example, the volume was removed during iteration). -
Similar to
os.walk()in Python. Returns aFileSystem::Walkobject. TheFileSystem::Walkobject can be used in a range-based for loop to enumerate the contents of a directory tree. Such a range-based for loop iterates over a sequence ofWalkTripleobjects, with oneWalkTripleobject for each directory in the tree rooted attop. It is recommended to iterate by reference in order to avoid copying theWalkTripleobject. EachWalkTripletakes the following form:struct WalkTriple { struct FileInfo { String name; u64 fileSize; // Only valid if WithSizes was specified double creationTime; // Only valid if WithTimes was specified double accessTime; double modificationTime; }; String dirPath; Array<String> dirNames; Array<FileInfo> files; };dirPathcontains the path to the directory.dirNamesis a list of the names of the subdirectories indirPathexcluding"."and"..".filesis a list ofWalkTriple::FileInfoobjects for the non-directory files indirPath.On each iteration of the loop, the caller can modify the
dirNameslist in-place, andwalk()will only recurse into the subdirectories whose names remain indirNames. This can be used to prune the search, impose a specific order of visiting, or informwalk()about directories that the caller creates or renames.The
flagsargument accepts a bitwise-or of zero or more of the following values:FileSystem::WithSizesFileSystem::WithFlags
The
fileSizemember ofWalkTriple::FileInfois only valid ifWithSizeswas set. ThecreationTime,accessTimeandmodificationTimemembers are only valid ifWithTimeswas set. Using these flags is likely faster than callinggetFileStatus()on the individual files, especially on Windows. Conversely, if the additional information is not needed, it might be faster to omit these flags on some platforms.The following example displays the number of bytes taken by non-directory files in each directory under the starting directory, except that it doesn't look under any subdirectory that starts with a dot
".":OutStream outs = StdOut::text(); for (WalkTriple& triple : fs->walk(".", FileSystem::WithSizes)) { // Calculate the number of bytes taken by non-directory files u64 sum = 0; for (const WalkTriple::FileInfo& file : triple.files) { sum += file.fileSize; } outs.format("{}: {} bytes\n", triple.dirPath, sum); // Prune subdirectories that start with "." for (u32 i = 0; i < triple.dirNames.numItems(); i++) { if (triple.dirNames[i].startsWith(".")) { triple.dirNames.erase(i); i--; } } }The initial call to
walk()updates the internal result code. Expected result codes areOK,NotFoundorAccessDenied. Each iteration of the loop updates the internal result code as well. Expected result codes areOK,NotFound(if, for example, the volume was removed during iteration) orAccessDenied. -
Creates a new directory. The parent directory must already exist.
This function updates the internal result code. The result code is also returned directly. Expected result codes are
OK,AlreadyExistsorAccessDenied. -
Recursive directory creation function. Like
makeDir(), but creates all intermediate-level directories needed to contain the leaf directory. Similar toos.makedirs()in Python.This function updates the internal result code. The result code is also returned directly. Expected result codes are
OKorAccessDenied. -
Renames the file at
srcPathtodstPath. IfdstPathalready exists and is a file, it will be silently replaced.This function updates the internal result code. The result code is also returned directly.
-
Deletes the file at
path.This function updates the internal result code. The result code is also returned directly.
-
Removes the directory tree at
path. The specified directory and all of its contents are deleted recursively.This function updates the internal result code. The result code is also returned directly. Expected result codes are
OKorAccessDenied. -
Returns a
FileStatusobject for the file located atpath.FileStatuscontains the following members:struct FileStatus { FSResult result; // Result of getFileStatus() u64 fileSize; // Size of the file in bytes double creationTime; // The file's POSIX creation time double accessTime; // The file's POSIX access time double modificationTime; // The file's POSIX modification time };creationTime,accessTimeandmodificationTimeare expressed in POSIX time, which is the number of seconds since January 1, 1970.This function updates the internal result code. The result code is also returned in the
resultmember. Expected result codes areOKorNotFound. -
Returns an
InPipethat reads the raw contents of the specified file, ornullptrif the file could not be opened.This function updates the internal result code. Expected result codes are
OK,NotFound,AccessDeniedorLocked.InPipeis a low-level class that doesn't perform any application-level buffering. If you plan to read small amounts of data at a time, such when parsing a text or binary file format, it is suggested to wrap the returnedInPipein anInStream. TheopenStreamForRead()convenience function is provided for this. -
Returns an
OutPipethat writes raw data to the specified file, ornullptrif the file could not be opened.This function updates the internal result code. Expected result codes are
OK,NotFound,AccessDeniedorLocked.OutPipeis a low-level class that doesn't perform any application-level buffering. If you plan to write small amounts of data at a time, such when writing a text or binary file format, it is suggested to wrap the returnedOutPipein anOutStream. TheopenStreamForWrite()convenience function is provided for this. -
Returns an
InStreamthat reads the raw contents of the specified file, ornullptrif the file could not be opened.This function updates the internal result code. Expected result codes are
OK,NotFoundorLocked. -
Returns an
OutStreamthat writes raw data to the specified file, ornullptrif the file could not be opened.This function updates the internal result code. Expected result codes are
OK,NotFound,AccessDeniedorLocked. -
Returns an
InStreamthat reads raw data from the specified text file and converts it to UTF-8 with Unix-style newlines, ornullptrif the file could not be opened. The text file is expected to have the file format described bytextFormat. Any byte order mark (BOM) in the file is skipped. SeeTextFormatfor more information on supported text file formats.This function updates the internal result code. Expected result codes are
OK,NotFound,AccessDeniedorLocked.The
openTextForRead()function is equivalent to the following:Owned<InStream> ins = fs->openStreamForRead(path); if (!ins) return nullptr; return textFormat.createImporter(std::move(ins)); -
Returns a
Tuple. The first tuple item is aInStreamthat reads raw data from the specified text file and converts it to UTF-8 with Unix-style newlines, ornullptrif the file could not be opened. The text file format is detected automatically and returned as the second tuple item. Any byte order mark (BOM) in the text file is skipped. SeeTextFormatfor more information on supported text file formats.This function updates the internal result code. Expected result codes are
OK,NotFound,AccessDeniedorLocked.The
openTextForReadAutodetect()function is equivalent to the following:Owned<InStream> ins = fs->openStreamForRead(path); if (!ins) return {nullptr, TextFormat{}}; TextFormat textFormat = TextFormat::autodetect(ins); return {textFormat.createImporter(std::move(ins)), textformat}; -
Returns a
Stringcontaining the raw contents of the specified file, or an emptyStringif the file could not be opened.To check if the file was opened successfuly, call
lastResult(). Expected result codes areOK,NotFound,AccessDeniedorLocked. -
Returns a
Stringcontaining the contents of the specified text file converted to UTF-8 with Unix-style newlines, or an emptyStringif the file could not be opened. The text file is expected to have the file format described bytextFormat. Any byte order mark (BOM) in the text file is skipped. SeeTextFormatfor more information on supported text file formats.To check if the file was opened successfuly, call
lastResult(). Expected result codes areOK,NotFound,AccessDeniedorLocked. -
Returns a
Tuple. The first tuple item is aStringcontaining the contents of the specified text file converted to UTF-8 with Unix-style newlines, or an emptyStringif the file could not be opened. The text file format is detected automatically and returned as the second tuple item. Any byte order mark (BOM) in the text file is skipped. SeeTextFormatfor more information on supported text file formats.To check if the file was opened successfuly, call
lastResult(). Expected result codes areOK,NotFound,AccessDeniedorLocked. -
Returns an
OutStreamthat writes text to the specified text file in the specified format, ornullptrif the file could not be opened. TheOutStreamexpects UTF-8-encoded text. TheOutStreamaccepts both Windows and Unix-style newlines; all newlines will be converted to the format described bytextFormat. SeeTextFormatfor more information on supported text file formats.This function updates the internal result code. Expected result codes are
OK,NotFound,AccessDeniedorLocked.The
openTextForWrite()function is equivalent to the following:Owned<OutStream> outs = fs->openTextForWrite(path); if (!outs) return nullptr; return TextFormat::createExporter(std::move(outs), textFormat); -
First, this function tries to load the raw contents of the specified file. If the load succeeds and its raw contents match
contentsexactly, the function returnsUnchanged. Otherwise, if the parent directories ofpathdon't exist, it attempts to create them. If that succeeds, it savescontentsto a temporary file in the same folder aspath. If that succeeds, it renames the temporary file topath, replacing any original contents.In all cases, this function updates the internal result code. The result code is also returned directly.
FSResult FileSystem::makeDirsAndSaveTextIfDifferent(StringView path, StringView strContents, const TextFormat& textFormat)[code]-
First, this function converts
strContentsto a raw memory buffer using the text file format specified bytextFormat. Then, it tries to load the raw contents of the specified file. If the load succeeds and its raw contents match the contents of the raw memory buffer exactly, the function returnsUnchanged. Otherwise, if the parent directories ofpathdon't exist, it attempts to create them. If that succeeds, it saves the raw memory buffer to a temporary file in the same folder aspath. If that succeeds, it renames the temporary file topath, replacing any original contents. SeeTextFormatfor more information on supported text file formats.In all cases, this function updates the internal result code. The result code is also returned directly.
-
Creates a virtual
FileSystemthat acts entirely within the directory specified byrootPath.The result virtual
FileSystemworks with POSIX-style paths, doesn't implementgetWorkingDirectoryorsetWorkingDirectory, and doesn't accept absolute paths as arguments to any of its member functions. Some of those restrictions might be removed in the future.