Linger.FileSystem.Ftp
2.0.0-preview.1
dotnet add package Linger.FileSystem.Ftp --version 2.0.0-preview.1
NuGet\Install-Package Linger.FileSystem.Ftp -Version 2.0.0-preview.1
<PackageReference Include="Linger.FileSystem.Ftp" Version="2.0.0-preview.1" />
<PackageVersion Include="Linger.FileSystem.Ftp" Version="2.0.0-preview.1" />
<PackageReference Include="Linger.FileSystem.Ftp" />
paket add Linger.FileSystem.Ftp --version 2.0.0-preview.1
#r "nuget: Linger.FileSystem.Ftp, 2.0.0-preview.1"
#:package Linger.FileSystem.Ftp@2.0.0-preview.1
#addin nuget:?package=Linger.FileSystem.Ftp&version=2.0.0-preview.1&prerelease
#tool nuget:?package=Linger.FileSystem.Ftp&version=2.0.0-preview.1&prerelease
Linger.FileSystem.Ftp
Breaking changes and 2.0 migration notes are documented in the Linger migration guide.
Overview
Linger.FileSystem.Ftp is an implementation of the Linger FileSystem abstraction that provides FTP file operations support. It uses the FluentFTP library to offer a robust and retry-capable FTP client for common file operations such as uploading, downloading, listing, and deleting files.
Installation
dotnet add package Linger.FileSystem.Ftp
Features
- File operations over FTP (upload, download, list, delete)
- Configurable retry policies for unstable networks
- Timeout configurations
- Seamless integration with other Linger.FileSystem components
- Supports multiple .NET frameworks (net9.0, net8.0, netstandard2.0)
Basic Usage
Creating an FTP File System Instance
// Create settings for remote FTP system
var settings = new FtpFileSystemOptions
{
Host = "ftp.example.com",
Port = 21,
UserName = "username",
Password = "password",
ConnectionTimeout = 15000, // 15 seconds
OperationTimeout = 60000 // 60 seconds
};
// Configure retry options
var retryOptions = new RetryOptions
{
MaxRetryAttempts = 3,
DelayMilliseconds = 1000,
MaxDelayMilliseconds = 5000
};
// Create FTP file system
using var ftpSystem = new FtpFileSystem(settings, retryOptions);
// Upload a file
await using var stream = File.OpenRead("./local/file.txt");
var result = await ftpSystem.UploadAsync(stream, "/remote/path/file.txt", overwrite: true);
if (result.Success)
{
Console.WriteLine($"Upload successful: {result.FilePath}");
}
// Download a file
var downloadResult = await ftpSystem.DownloadFileAsync("/remote/path/file.txt", "C:/Downloads/file.txt");
if (downloadResult.Success)
{
var downloadedBytes = await ftpSystem.GetFileSizeAsync("/remote/path/file.txt");
Console.WriteLine($"Downloaded {downloadedBytes} bytes");
}
FTP Client Encoding
FtpFileSystemOptions.Encoding configures the encoding used by the FTP client for protocol text and remote path names. It defaults to UTF-8 when omitted:
var settings = new FtpFileSystemOptions
{
Host = "ftp.example.com",
UserName = "username",
Password = "password",
Encoding = System.Text.Encoding.UTF8
};
This option does not control file-content encoding. Pass the required encoding to GetReaderAsync or GetWriterAsync when reading or writing text files.
File Upload Methods
// Method 1: Upload from stream to complete file path
await using var stream = File.OpenRead("local.txt");
var result = await ftpSystem.UploadAsync(stream, "/remote/path/file.txt", overwrite: true);
// Method 2: Upload local file to complete remote path
result = await ftpSystem.UploadFileAsync("C:/local/file.txt", "/remote/path/file.txt", overwrite: true);
Integration with Dependency Injection
// In your startup class
public void ConfigureServices(IServiceCollection services)
{
services.AddTransient<IRemoteFileSystem>(provider => {
var settings = new FtpFileSystemOptions
{
Host = "ftp.example.com",
Port = 21,
UserName = "username",
Password = "password",
ConnectionTimeout = 15000,
OperationTimeout = 60000
};
var retryOptions = new RetryOptions
{
MaxRetryAttempts = 3,
DelayMilliseconds = 1000,
MaxDelayMilliseconds = 5000
};
return new FtpFileSystem(settings, retryOptions);
});
}
FtpFileSystem automatically connects on the first operation and keeps one client connection per instance. Do not
invoke operations concurrently on the same instance or mutate its working directory while another operation is running.
FtpFileSystem implements IAsyncRemoteFileSystem. Use the concrete type or this capability interface when asynchronous
disposal is required; the general IRemoteFileSystem contract provides synchronous disposal.
Advanced Features
Working Directory Management
// Set working directory
await ftpSystem.SetWorkingDirectoryAsync("/public_html");
Directory Listing and Manipulation
// List files
var files = await ftpSystem.ListFilesAsync("/public_html");
foreach (var file in files)
{
Console.WriteLine($"File: {file}");
}
// Create directory
await ftpSystem.CreateDirectoryIfNotExistsAsync("/public_html/uploads");
// Check if directory exists
bool exists = await ftpSystem.DirectoryExistsAsync("/public_html/uploads");
Custom Connection Settings
var settings = new FtpFileSystemOptions
{
Host = "ftp.example.com",
Port = 21,
UserName = "username",
Password = "password",
ConnectionTimeout = 30000, // 30 seconds connection timeout
OperationTimeout = 120000, // 2 minutes operation timeout
Type = "FTP"
};
// Advanced retry configuration
var retryOptions = new RetryOptions
{
MaxRetryAttempts = 5,
DelayMilliseconds = 2000,
MaxDelayMilliseconds = 30000,
UseExponentialBackoff = true // Use exponential backoff for retries
};
var ftpSystem = new FtpFileSystem(settings, retryOptions);
File Information and Metadata
// Get file size
long? fileSize = await ftpSystem.GetFileSizeAsync("/remote/file.txt");
// Get file last modified time
DateTime modTime = await ftpSystem.GetModifiedTimeAsync("/remote/file.txt");
// Check if file exists
bool exists = await ftpSystem.FileExistsAsync("/remote/file.txt");
Connection Lifetime
using (var ftpSystem = new FtpFileSystem(settings))
{
// The first operation establishes the connection; disposal closes it.
await ftpSystem.UploadFileAsync("local.txt", "/remote/path");
await ftpSystem.DownloadFileAsync("/remote/file.txt", "downloaded.txt");
}
Error Handling and Troubleshooting
Common FTP Exceptions
try
{
await ftpSystem.UploadFileAsync("local.txt", "/remote/path");
}
catch (FileSystemException ex)
{
switch (ex.Operation)
{
case "Upload":
Console.WriteLine($"Upload failed: {ex.Message}");
break;
case "Connect":
Console.WriteLine($"Connection failed: {ex.Message}");
break;
}
}
catch (TimeoutException ex)
{
Console.WriteLine($"Operation timed out: {ex.Message}");
}
Retry Configuration for Unstable Networks
var retryOptions = new RetryOptions
{
MaxRetryAttempts = 10, // Retry up to 10 times
DelayMilliseconds = 1000, // Start with 1 second delay
MaxDelayMilliseconds = 60000, // Maximum 60 seconds delay
UseExponentialBackoff = true // Increase delay exponentially
};
var ftpSystem = new FtpFileSystem(settings, retryOptions);
Dependencies
- FluentFTP: Modern FTP client library
- Linger.FileSystem: Core abstraction library
License
This project is licensed under the terms of the license provided with the Linger project.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. 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 is compatible. 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 is compatible. 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 is compatible. 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 was computed. |
| .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
- FluentFTP (>= 54.2.0)
- Linger.FileSystem (>= 2.0.0-preview.1)
-
net10.0
- FluentFTP (>= 54.2.0)
- Linger.FileSystem (>= 2.0.0-preview.1)
-
net8.0
- FluentFTP (>= 54.2.0)
- Linger.FileSystem (>= 2.0.0-preview.1)
-
net9.0
- FluentFTP (>= 54.2.0)
- Linger.FileSystem (>= 2.0.0-preview.1)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 2.0.0-preview.1 | 0 | 8/29/2026 |
| 1.6.4 | 90 | 8/16/2026 |
| 1.6.3 | 94 | 8/5/2026 |
| 1.6.2 | 111 | 8/2/2026 |
| 1.6.0 | 110 | 7/25/2026 |
| 1.5.5 | 107 | 7/23/2026 |
| 1.5.4-preview | 84 | 7/21/2026 |
| 1.5.3-preview | 95 | 7/20/2026 |
| 1.5.2-preview | 93 | 7/19/2026 |
| 1.5.1-preview | 94 | 7/15/2026 |
| 1.5.0-preview | 89 | 7/14/2026 |
| 1.4.4-preview | 109 | 6/16/2026 |
| 1.4.3-preview | 107 | 6/15/2026 |
| 1.4.2 | 122 | 5/20/2026 |
| 1.4.1-preview | 109 | 5/12/2026 |
| 1.4.0 | 112 | 5/6/2026 |
| 1.3.3-preview | 102 | 5/5/2026 |
| 1.3.2-preview | 106 | 4/29/2026 |
| 1.3.1-preview | 110 | 4/28/2026 |
| 1.3.0-preview | 107 | 4/27/2026 |