Files
VirtualFS/docs/usage.md

3.8 KiB

Usage

Quick Start

Create a Root Filesystem

using System.IO;
using VirtualFS;
using VirtualFS.Implementation;
using VirtualFS.Memory;
using VirtualFS.Physical;

var root = new RootFileSystem();

var physical = new PhysicalFileSystem(new DirectoryInfo("/srv/site"));
var generated = new MemoryFileSystem
{
    Priority = FileSystemMountPriority.High
};

root.Mount(physical, "/");
root.Mount(generated, "/");

In this setup:

  • files present in generated can override files from physical
  • reads are resolved through the root
  • writes go to the writable backend chosen for the path

Creating and Reading Files

var file = root.Root.FileCreate("hello.txt");
file.WriteAllText("Hello from VirtualFS");

string text = root.GetFile("/hello.txt").ReadAllText();

Working Inside a Mounted Subtree

root.Mount(new MemoryFileSystem(), "/cache/");

var cacheDir = root.GetDirectory("/cache/");
cacheDir.Create("images");
cacheDir.GetDirectory("images/").FileCreate("thumb.txt").WriteAllText("ok");

Overlay Example

using System.IO;
using VirtualFS;
using VirtualFS.Compressed;
using VirtualFS.Implementation;
using VirtualFS.Physical;

var root = new RootFileSystem();

var baseAssets = new ZipReadFileSystem(System.IO.File.OpenRead("base-assets.zip"))
{
    Priority = FileSystemMountPriority.Low
};

var overrides = new PhysicalFileSystem(new DirectoryInfo("./overrides"))
{
    Priority = FileSystemMountPriority.High
};

root.Mount(baseAssets, "/assets/");
root.Mount(overrides, "/assets/");

Reads under /assets/ prefer files from ./overrides, then fall back to the ZIP.

Enumerating Entries

foreach (var entry in root.Root.GetEntries())
{
    Console.WriteLine($"{entry.FullPath} readonly={entry.IsReadOnly}");
}

You can also enumerate only files or only directories:

  • GetFiles()
  • GetDirectories()

All enumeration methods support an optional regular-expression filter.

Using Directory

Common operations:

  • GetEntries()
  • GetFiles()
  • GetDirectories()
  • Exists(name)
  • GetEntry(name)
  • GetFile(name)
  • GetDirectory(name)
  • Create(name)
  • FileCreate(name)
  • Delete(recursive)

Example:

var dir = root.GetDirectory("/content/");

if (!dir.Exists("images/"))
    dir.Create("images");

var imageDir = dir.GetDirectory("images/");

Using File

Common operations:

  • OpenRead()
  • OpenWrite()
  • ReadAllBytes()
  • ReadAllLines()
  • ReadAllText()
  • WriteAllBytes()
  • WriteAllLines()
  • WriteAllText()
  • AppendAllBytes()
  • AppendAllLines()
  • AppendAllText()
  • Delete()

Example:

var file = root.GetFile("/config/appsettings.json");
var text = file.ReadAllText();

forceLocal

Many Directory and File instance methods accept forceLocal.

Use it when:

  • you explicitly want to bypass the root overlay behavior
  • you want to operate only inside the backend that produced the entry

Example:

var entry = root.GetFile("/assets/logo.png");
using var localStream = entry.OpenRead(forceLocal: true);

Path Examples

Path dir = "/docs/";
Path file = dir + "readme.txt";     // "/docs/readme.txt"
Path parent = ((Path)"/docs/api/").Parent; // "/docs/"

Normalization:

  • "/a/./b.txt" becomes "/a/b.txt"
  • "/a/b/../c.txt" becomes "/a/c.txt"

Copy, Move, Rename

Available on IFileSystem:

  • Copy
  • Move
  • ReName

Notes:

  • copy and move may work across different mounted backends
  • cross-backend operations may be slower
  • directory destinations are expected to be directory paths

Unmounting

Umount succeeds only if the filesystem is not busy.

That means:

  • open file streams must be closed first
  • callers should use using or explicit disposal

Example:

using (var stream = root.GetFile("/data/report.txt").OpenRead())
{
    // use stream
}

root.Umount(someFs);