Add structured project documentation
This commit is contained in:
205
docs/usage.md
Normal file
205
docs/usage.md
Normal file
@@ -0,0 +1,205 @@
|
||||
# Usage
|
||||
|
||||
## Quick Start
|
||||
|
||||
### Create a Root Filesystem
|
||||
|
||||
```csharp
|
||||
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
|
||||
|
||||
```csharp
|
||||
var file = root.Root.FileCreate("hello.txt");
|
||||
file.WriteAllText("Hello from VirtualFS");
|
||||
|
||||
string text = root.GetFile("/hello.txt").ReadAllText();
|
||||
```
|
||||
|
||||
## Working Inside a Mounted Subtree
|
||||
|
||||
```csharp
|
||||
root.Mount(new MemoryFileSystem(), "/cache/");
|
||||
|
||||
var cacheDir = root.GetDirectory("/cache/");
|
||||
cacheDir.Create("images");
|
||||
cacheDir.GetDirectory("images/").FileCreate("thumb.txt").WriteAllText("ok");
|
||||
```
|
||||
|
||||
## Overlay Example
|
||||
|
||||
```csharp
|
||||
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
|
||||
|
||||
```csharp
|
||||
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:
|
||||
|
||||
```csharp
|
||||
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:
|
||||
|
||||
```csharp
|
||||
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:
|
||||
|
||||
```csharp
|
||||
var entry = root.GetFile("/assets/logo.png");
|
||||
using var localStream = entry.OpenRead(forceLocal: true);
|
||||
```
|
||||
|
||||
## Path Examples
|
||||
|
||||
```csharp
|
||||
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:
|
||||
|
||||
```csharp
|
||||
using (var stream = root.GetFile("/data/report.txt").OpenRead())
|
||||
{
|
||||
// use stream
|
||||
}
|
||||
|
||||
root.Umount(someFs);
|
||||
```
|
||||
Reference in New Issue
Block a user