-
Notifications
You must be signed in to change notification settings - Fork 0
Driver Local
Wraps System.IO.File / System.IO.Directory. Ships in the core FileHub package.
using FileHub.Local;
var hub = new LocalFileHub(@"C:\data");The root is created automatically if it doesn't exist.
| Constructor | Use |
|---|---|
LocalFileHub(rootPath) |
Absolute or relative path. Relative resolves against the current working directory. Leading ~ resolves against AppDomain.CurrentDomain.BaseDirectory. |
// Absolute
var hub = new LocalFileHub(@"C:\data");
// XDG-style — compute the full path up-front
var root = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
"MyApp", "data");
var hub = new LocalFileHub(root);Nested directory paths ("a/b/c") resolve in one shot: Directory.CreateDirectory creates every intermediate in a single syscall, and TryOpenDirectory checks the full path with one Directory.Exists.
CopyTo and MoveTo (and their async siblings) accept an optional IProgress<TransferStatus>. Transfers stream through a chunked read/write loop and report byte-level progress as they go.
var progress = new Progress<TransferStatus>(s =>
Console.WriteLine($"{s.BytesTransferred}/{s.TotalBytes}"));
hub.Root.OpenFile("big.bin").CopyTo(dstDir, "big.bin", progress);CopyTo / MoveTo default to overwrite: false: an existing destination throws FileAlreadyExistsException and the source stays intact, nothing is written. A file never overwrites a directory. Pass overwrite: true to replace an existing destination. A file CopyTo / MoveTo onto an existing destination is refused unless overwrite: true.
For a directory MoveTo(dir, name, overwrite: false) the atomic Directory.Move fast path is only taken when the destination does not exist. An existing destination throws FileAlreadyExistsException; pass overwrite: true to merge into it (copy + delete) instead of the atomic move.
Rename never overwrites: renaming onto a name already taken (file or directory) throws FileAlreadyExistsException, and any raw System.IO.IOException from File.Move / Directory.Move is wrapped so no BCL exception leaks to callers.
public interface ILocalFileHub : IFileHub { }
public class LocalFileHub : ILocalFileHub { ... }Inject ILocalFileHub when you want to bind to the local driver specifically; IFileHub when backend-agnostic.
A LocalFile can also be built directly, anchored to an existing LocalDirectory:
var directory = (LocalDirectory)hub.Root.OpenDirectory("reports", createIfNotExists: true);
var reference = new LocalFile(directory, "q4.pdf");
if (!reference.Exists())
reference.SetBytes(bytes);The file isn't created on disk until you write to it (SetText, SetBytes, GetWriteStream). Raw disk paths are deliberately not accepted — the reference always carries the hub's sandbox root.
An OS access-denied error surfaces as UnauthorizedAccessException, propagated as-is — the Local driver no longer wraps it in FileHubException. This matches every other backend.
Rename(newName) is leaf-only: a newName containing / or \ throws ArgumentException. Use MoveTo to relocate an entry into a different directory.
Resolved against the root and checked on every call. .., absolute paths, and separators in leaf names all throw — see Security.
-
GetFiles/GetDirectoriesskip any entry withFileAttributes.ReparsePoint(symlinks, junctions, mount points) on both target frameworks. - On
net8.0, path resolution additionally callsFileSystemInfo.ResolveLinkTarget(true)— a symlink whose final target is outside the root is rejected when opened by name.
FileExists(name) and DirectoryExists(name) map directly to System.IO.File.Exists / System.IO.Directory.Exists after sandbox resolution. Each is a single OS call.
CreateFile("a/b/c.txt") (and OpenFile / TryOpenFile) creates the file at the nested location, auto-creating the intermediate directories with Directory.CreateDirectory first. Both / and \ separators work; .. is rejected with FileHubException.
hub.Root.CreateFile("reports/2026/q1.pdf").SetText("...");
// Equivalent to: CreateDirectory("reports/2026"); then CreateFile("q1.pdf").var hub = new LocalFileHub(@"C:\data");
var logs = hub.Root.CreateDirectory("2026/01/logs");
logs.CreateFile("app.log").SetText("ready");
foreach (var f in hub.Root.GetFiles("*.log"))
Console.WriteLine($"{f.Name}: {f.Length} bytes");Every method, signature, and async counterpart: API reference.
FileHub — unified file & directory API for .NET. Core is dependency-free; drivers are opt-in packages.