Lightweight, unified file system API for .NET. Read, write, copy, move, sync and version files the same way whether they live on the local disk, an in-memory virtual tree, or any other TagBites.IO-supported storage (FTP, SFTP, SMB, WebDAV, HTTP, ZIP, Dropbox, OneDrive, Google Cloud Storage, Azure Blob Storage, S3, ...).
The FileSystem API stays the same when the underlying storage changes - local disk in development, S3 or FTP in production - so the rest of the code does not change.
dotnet add package TagBites.IO
Local disk, an in-memory file system, and a virtual composed tree are built in. Remote storages ship as separate packages that plug into the same API:
| Package | Storage |
|---|---|
| TagBites.IO.Ftp | FTP/FTPS |
| TagBites.IO.Sftp | SFTP |
| TagBites.IO.Smb | SMB/CIFS network shares |
| TagBites.IO.WebDav | WebDAV |
| TagBites.IO.Http | Read-only HTTP |
| TagBites.IO.Zip | ZIP archives |
| TagBites.IO.Dropbox | Dropbox |
| TagBites.IO.OneDrive | OneDrive (Microsoft Graph) |
| TagBites.IO.Google | Google Cloud Storage |
| TagBites.IO.AzureBlob | Azure Blob Storage |
| TagBites.IO.S3 | Amazon S3 / S3-compatible storage (e.g. Cloudflare R2) |
| TagBites.IO.WinDrive | Mount any of the above as a Windows drive letter (Dokan) |
using TagBites.IO;
// Built-in: local disk
var fs = FileSystem.Local;
// Or an in-memory file system, useful for tests
// var fs = FileSystem.CreateMemory();
var directory = fs.GetDirectory("/some/folder");
directory.Create();
var file = fs.GetFile("/some/folder/file.txt");
file.WriteAllText("Hello world!");
var content = file.ReadAllText(); // "Hello world!"
foreach (var f in directory.GetFiles(recursive: true))
Console.WriteLine(f.FullName);Every provider package (TagBites.IO.Ftp, TagBites.IO.S3, ...) exposes the same shape - a static Create(...) method returning a FileSystem - so the code above works unchanged regardless of the storage:
using TagBites.IO.Ftp;
var fs = FtpFileSystem.Create("ftp.example.com", "user", "password");
var file = fs.GetFile("/reports/2024/summary.csv");using TagBites.IO;
sourceFile.Copy(destinationFile, overwrite: true);
sourceDirectory.Move(destinationDirectory);
sourceDirectory.SyncWith(destinationDirectory, FileSystemSynchronizeMode.OneWayWithRemoveNotExisting);Every read/write operation has an async counterpart (ReadAllTextAsync, WriteAllTextAsync, CopyAsync, SyncWithAsync, ...).
The VirtualDirectory and VirtualDirectoryEntry types (IO/Virtual) mount links from several file systems - local, FTP, ZIP, cloud storage - as entries of a single logical directory tree, so consumers only ever see one FileSystem.
See https://www.tagbites.com/io for licensing terms.