File System
(ply-system.h)
Plywood provides a portable file system API that works consistently across Windows and POSIX platforms. All paths arguments are treated as UTF-8 strings.
FileSystem
The FileSystem class contains static methods for file and directory operations.
static FSResult FileSystem::lastResult()Returns the result code from the most recent file system operation.
static Array<DirectoryEntry> FileSystem::listDir(StringView path)Returns an array of directory entries for the given path. Each entry contains the name, size, and type of a file or subdirectory.
static FSResult FileSystem::makeDir(StringView path)Creates a single directory. The parent directory must already exist.
static Path_t FileSystem::pathFormat()Returns the native path format for the current platform (Windows or POSIX).
static String FileSystem::getWorkingDirectory()Returns the current working directory as an absolute path.
static FSResult FileSystem::setWorkingDirectory(StringView path)Changes the current working directory.
static ExistsResult FileSystem::exists(StringView path)Checks if a file or directory exists at the given path.
static Owned<Pipe> FileSystem::openPipeForRead(StringView path)Opens a file for reading and returns a pipe. Returns null if the file doesn't exist.
static Owned<Pipe> FileSystem::openPipeForWrite(StringView path)Opens a file for writing and returns a pipe. Creates the file if it doesn't exist.
static FSResult FileSystem::moveFile(StringView srcPath, StringView dstPath)Moves or renames a file.
static FSResult FileSystem::deleteFile(StringView path)Deletes a file. Does not delete directories.
static FSResult FileSystem::removeDirTree(StringView dirPath)Recursively deletes a directory and all its contents.
static DirectoryEntry FileSystem::getFileInfo(StringView path)Returns information about a file or directory.
static FSResult FileSystem::copyFile(StringView srcPath, StringView dstPath)Copies a file to a new location.
static bool FileSystem::isDir(StringView path)Returns
trueif the path is a directory.static DirectoryWalker FileSystem::walk(StringView top)Returns an iterator for recursively walking a directory tree.
static FSResult FileSystem::makeDirs(StringView path)Creates a directory and all necessary parent directories.
static Stream FileSystem::openBinaryForRead(StringView path)Opens a file for binary reading and returns a buffered stream.
static Stream FileSystem::openBinaryForWrite(StringView path)Opens a file for binary writing and returns a buffered stream.
static Stream FileSystem::openTextForRead(StringView path, const TextFormat& format)Opens a file for text reading with the specified encoding.
static Stream FileSystem::openTextForReadAutodetect(StringView path, TextFormat* outFormat)Opens a file for text reading, automatically detecting the encoding from byte-order marks.
static Stream FileSystem::openTextForWrite(StringView path, const TextFormat& format)Opens a file for text writing with the specified encoding.
static String FileSystem::loadBinary(StringView path)Loads an entire file into memory as raw bytes.
static String FileSystem::loadText(StringView path, const TextFormat& format)Loads an entire text file into memory, converting to UTF-8.
static String FileSystem::loadTextAutodetect(StringView path, TextFormat* outFormat)Loads an entire text file, auto-detecting the encoding.
static FSResult FileSystem::saveBinary(StringView path, StringView contents)Writes raw bytes to a file, replacing any existing contents.
static FSResult FileSystem::saveText(StringView path, StringView strContents, const TextFormat& format)Writes text to a file with the specified encoding.
TextFormat
TextFormat describes the encoding and line-ending style of a text file. Common formats include UTF-8, UTF-16 (big and little endian), and various legacy encodings.
Manipulating Paths
These functions help you parse and construct file paths in a platform-independent way.
char getPathSeparator()Returns the native path separator character:
'/'on POSIX,'\\'on Windows.bool isPathSeparator(char c)Returns
trueifcis '/'. Also matches '\' on Windows.StringView getDriveLetter(StringView path)Returns the drive letter prefix (e.g.,
"C:") from a Windows path, or an empty view on POSIX.bool isAbsolutePath(StringView path)Returns
trueif the path is absolute (starts with/on POSIX or a drive letter on Windows).bool isRelativePath(StringView path)Returns
trueif the path is relative.String makeAbsolutePath(StringView path)Converts a relative path to an absolute path using the current working directory.
String makeRelativePath(StringView ancestor, StringView descendant)Returns
descendantas a path relative toancestor.SplitPath splitPath(StringView path)Splits a path into directory and filename components.
SplitExtension splitFileExtension(StringView path)Splits a filename into base name and extension.
Array<StringView> splitPathFull(StringView path)Splits a path into all of its individual components.
String joinPath(StringViews&& pathComponentArgs)Joins path components with the native separator.
bool matchGlobPattern(StringView str, StringView pattern, GlobOptions options)Returns
trueifstris matched by a single-component glob pattern. Recognizes*,?, bracket expressions such as[abc], ranges such as[a-z], inverted bracket expressions such as[!abc], POSIX character classes such as[[:digit:]], and backslash escapes.bool matchGitIgnorePattern(StringView relativePath, bool isDir, StringView pattern)Returns
trueifrelativePathis ignored by one.gitignore-style pattern.
String fullPath = Path::joinPath("home", "user", "documents", "file.txt");
// On POSIX: "home/user/documents/file.txt"
// On Windows: "home\\user\\documents\\file.txt"
auto [dir, file] = Path::splitPath("/home/user/test.cpp");
// The directory is "/home/user" and the file is "test.cpp".
bool ignored = matchGitIgnorePattern("build/output.o", false, "build/");
// The path is ignored.
DirectoryWatcher
DirectoryWatcher monitors a directory tree for file and directory changes, invoking a callback whenever modifications are detected. This is useful for applications that need to react to file changes in real-time, such as live-reload servers or file synchronization tools.
When mustRecurse is false, the path refers to a specific file that changed.
DirectoryWatcher is only supported on Windows and macOS and is not enabled by default. To enable it, define PLY_WITH_DIRECTORY_WATCHER in your project settings. If enabled on macOS, you must also link with the CoreServices framework.
DirectoryWatcher::DirectoryWatcher()Default constructor. Creates an inactive watcher. Call
start()to begin watching.DirectoryWatcher::DirectoryWatcher(StringView root, Functor<void(StringView path, bool mustRecurse)>&& callback)Constructs and immediately starts watching the directory at
root.void DirectoryWatcher::start(StringView root, Functor<void(StringView path, bool mustRecurse)>&& callback)Begins watching the directory tree rooted at
root. Thecallbackwill be invoked from a background thread whenever changes are detected. The watcher must not already be running.void DirectoryWatcher::stop()Stops the background watcher thread and waits for it to finish. After calling
stop(), you may callstart()again with a new root and callback. The destructor callsstop()automatically.
// Watch a directory and log changes.
DirectoryWatcher watcher;
watcher.start("/path/to/watch", [](StringView path, bool mustRecurse) {
if (mustRecurse) {
// Too many changes or directory modified; rescan this path.
puts(String::format("Rescan needed: {}", path).bytes);
} else {
// Single file changed.
puts(String::format("File changed: {}", path).bytes);
}
});
// ... do other work ...
// Stop watching (also happens automatically in destructor).
watcher.stop();