TagBites.IO
2.0.0
Prefix Reserved
dotnet add package TagBites.IO --version 2.0.0
NuGet\Install-Package TagBites.IO -Version 2.0.0
<PackageReference Include="TagBites.IO" Version="2.0.0" />
<PackageVersion Include="TagBites.IO" Version="2.0.0" />
<PackageReference Include="TagBites.IO" />
paket add TagBites.IO --version 2.0.0
#r "nuget: TagBites.IO, 2.0.0"
#:package TagBites.IO@2.0.0
#addin nuget:?package=TagBites.IO&version=2.0.0
#tool nuget:?package=TagBites.IO&version=2.0.0
TagBites.IO
TagBites.IO turns any storage into the same thing: a FileSystem browsed with FileLink and DirectoryLink. The local disk, an in-memory tree and a composed virtual tree are built in, and separate packages add FTP, SFTP, SMB, WebDAV, HTTP, ZIP, Dropbox, OneDrive, Google Cloud Storage, Azure Blob Storage and S3. An operation is written once - copy, move, sync, watch, restore a version - and runs wherever the files live, without a provider-specific SDK.
One API, any storage
Restore yesterday's FTP backup to disk:
using var ftp = FtpFileSystem.Create("ftp.example.com", "user", "password");
var backup = ftp.GetDirectory("/backups/2026-07-04");
var restore = FileSystem.Local.GetDirectory("C:/Restore");
backup.CopyTo(restore);
Turn an S3 bucket, a Dropbox account and a local folder into one Windows drive:
var s3 = S3FileSystem.Create(serviceUrl, accessKey, secretKey, "bucket");
var dropbox = DropboxFileSystem.Create(dropboxToken);
var backups = s3.GetDirectory("backups");
var photos = dropbox.GetDirectory("Photos");
var files = FileSystem.Local.GetDirectory("C:/Files");
var merged = new VirtualDirectory
{
Entries =
{
new VirtualDirectoryEntry(backups, "S3"),
new VirtualDirectoryEntry(photos, "Dropbox"),
new VirtualDirectoryEntry(files, "Local")
}
};
using var drive = new WinDrive(merged.ToDirectory()) { Name = "Merged Drive" };
drive.Mount(); // "V:\S3", "V:\Dropbox", "V:\Local"
Install
dotnet add package TagBites.IO
Targets netstandard2.0, netstandard2.1 and net5.0. No dependencies.
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:
| File system | Package | Storage |
|---|---|---|
FileSystem.Local |
TagBites.IO |
Local disk (System.IO) |
MemoryFileSystem.CreateMemory |
TagBites.IO |
In-memory tree, held for the lifetime of the instance |
VirtualFileSystem |
TagBites.IO |
Several file systems composed into one tree |
FtpFileSystem |
TagBites.IO.Ftp |
FTP / FTPS |
SftpFileSystem |
TagBites.IO.Sftp |
SFTP |
SmbFileSystem |
TagBites.IO.Smb |
SMB/CIFS network shares |
WebDavFileSystem |
TagBites.IO.WebDav |
WebDAV |
HttpFileSystem |
TagBites.IO.Http |
HTTP, read-only |
ZipFileSystem |
TagBites.IO.Zip |
ZIP archives |
DropboxFileSystem |
TagBites.IO.Dropbox |
Dropbox |
OneDriveFileSystem |
TagBites.IO.OneDrive |
OneDrive (Microsoft Graph) |
GoogleFileSystem |
TagBites.IO.Google |
Google Cloud Storage |
AzureBlobFileSystem |
TagBites.IO.AzureBlob |
Azure Blob Storage |
S3FileSystem |
TagBites.IO.S3 |
Amazon S3 and S3-compatible storage (e.g. Cloudflare R2) |
and also allows to create custom file system.
TagBites.IO.WinDrive lets you mount any DirectoryLink - regardless of the underlying file system - as a real Windows drive letter.
Usage
var fs = FileSystem.Local;
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 var fs = FtpFileSystem.Create("ftp.example.com", "user", "password");
var file = fs.GetFile("/reports/2024/summary.csv");
Copy, move and sync
Source and destination can live in different storages:
using var ftp = FtpFileSystem.Create("ftp.example.com", "user", "password");
using var s3 = S3FileSystem.Create(serviceUrl, accessKey, secretKey, "archive");
var reports = ftp.GetDirectory("/reports");
var archive = s3.GetDirectory("/reports");
reports.Copy(archive, overwrite: true);
reports.Move(archive);
reports.SyncWith(archive, FileSystemSynchronizeMode.OneWayWithRemoveNotExisting);
What happens when the destination exists, and what happens when one file in a tree fails, is decided per call - see conflicts and errors.
Live synchronization
SyncWith runs once. FileSystemLinkSynchronizer keeps a pair in step for as long as it is enabled, across two different storages:
using var ftp = FtpFileSystem.Create("ftp.example.com", "user", "password");
var local = FileSystem.Local.GetDirectory("C:/Reports");
var remote = ftp.GetDirectory("/reports");
using var synchronizer = new FileSystemLinkSynchronizer();
synchronizer.Add(local, remote, FileSystemSynchronizeMode.BothWaysUsingLastWriteTime);
synchronizer.SyncFailed += (_, e) =>
Console.WriteLine($"{e.Source.FullName}: {e.Exception.Message}, retry: {e.WillRetry}");
synchronizer.Enabled = true;
Change detection uses the same watcher the provider reports through FileSystemFeatures.Watcher. A storage without one notices only the changes made through the registered FileSystem instances, so call ForceSyncAsync() on a timer to catch what another client wrote:
await synchronizer.ForceSyncAsync();
See synchronization for what each mode does and what a watcher on a remote storage does not see.
File versions
A file system whose operations implement IFileSystemHistoryOperations exposes previous versions of a file:
var versions = file.GetHistoryVersions();
foreach (var version in versions)
Console.WriteLine($"{version.ModifyTime} {version.Length}");
var previous = versions[0];
using var stream = previous.Read(); // the content of that version, without restoring it
previous.Restore();
No shipped provider implements file history yet. The API is there for a custom file system built over a storage that keeps versions - see file history and versioning.
Links
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 is compatible. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 is compatible. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- No dependencies.
-
.NETStandard 2.1
- No dependencies.
-
net5.0
- No dependencies.
NuGet packages (13)
Showing the top 5 NuGet packages that depend on TagBites.IO:
| Package | Downloads |
|---|---|
|
VendoStandard
Common API for Vendo Lite, Vendo Server and Vendo ERP Desktop projects. |
|
|
TagBites.IO.Http
Read-only HTTP file system support for TagBites.IO. Browse and read files published over plain HTTP through the same FileSystem API used for local disk and other storages. |
|
|
TagBites.IO.Ftp
FTP/FTPS file system support for TagBites.IO, built on FluentFTP. Browse, read, write and sync a remote FTP server through the same FileSystem API used for local disk and other storages. |
|
|
TagBites.IO.Zip
ZIP archive file system support for TagBites.IO, built on SharpZipLib. Read and write the contents of a .zip file (optionally password-protected) through the same FileSystem API used for local disk and other storages. |
|
|
TagBites.IO.WinDrive
Mount any TagBites.IO file system - local disk, FTP, ZIP, Dropbox, S3, a virtual composed tree, etc. - as a real Windows drive letter, using Dokan. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 2.0.0 | 497 | 8/23/2026 |
| 1.3.13 | 644 | 3/13/2026 |
| 1.3.11 | 4,038 | 1/17/2025 |
| 1.3.10 | 347 | 5/27/2024 |
| 1.3.9 | 558 | 3/23/2024 |
| 1.3.8 | 721 | 3/21/2024 |
| 1.3.7 | 299 | 2/24/2024 |
| 1.3.6 | 1,971 | 2/2/2024 |
| 1.3.5 | 353 | 1/1/2024 |
| 1.3.4 | 347 | 11/30/2023 |
| 1.3.3 | 368 | 10/14/2023 |
| 1.3.2 | 538 | 10/3/2023 |
| 1.3.1 | 361 | 8/21/2023 |
| 1.3.0 | 774 | 6/28/2023 |
| 1.2.1 | 363 | 5/16/2023 |
| 1.2.0 | 985 | 2/17/2023 |
| 1.1.1 | 516 | 1/24/2023 |
| 1.1.0 | 1,616 | 10/23/2021 |