Robbiblubber.Util.FileStorageAdapters.Ftp 1.0.2

dotnet add package Robbiblubber.Util.FileStorageAdapters.Ftp --version 1.0.2
                    
NuGet\Install-Package Robbiblubber.Util.FileStorageAdapters.Ftp -Version 1.0.2
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Robbiblubber.Util.FileStorageAdapters.Ftp" Version="1.0.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Robbiblubber.Util.FileStorageAdapters.Ftp" Version="1.0.2" />
                    
Directory.Packages.props
<PackageReference Include="Robbiblubber.Util.FileStorageAdapters.Ftp" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Robbiblubber.Util.FileStorageAdapters.Ftp --version 1.0.2
                    
#r "nuget: Robbiblubber.Util.FileStorageAdapters.Ftp, 1.0.2"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Robbiblubber.Util.FileStorageAdapters.Ftp@1.0.2
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Robbiblubber.Util.FileStorageAdapters.Ftp&version=1.0.2
                    
Install as a Cake Addin
#tool nuget:?package=Robbiblubber.Util.FileStorageAdapters.Ftp&version=1.0.2
                    
Install as a Cake Tool

robbiblubber.org FTP File Storage Adapter Library

The robbiblubber.org FTP File Storage Adapter Library provides access to FTP and FTPS servers through the common API defined by the FileStorageAdapters Library. Files and directories are exposed through IFile, IDirectory, and IElement.

The repository can be found at https://bitbucket.org/robbiblubber/robbiblubber.util.filestorageadapters.net/. API documentation is available from https://robbiblubber.lima-city.org/. For general information see http://robbiblubber.org/.

The library is provided under the MIT license and may be used under the conditions of that license agreement.

Opening a Directory

Connection behavior can be configured with FtpAdapterOptions:

using Robbiblubber.Util.FileStorageAdapters;
using Robbiblubber.Util.FileStorageAdapters.Ftp;

FtpAdapterOptions options = new()
{
    Security = FtpSecurity.ExplicitTls,
    DataConnectionMode = FtpDataConnectionMode.Passive,
    InternetProtocol = FtpInternetProtocol.Any,
    ConnectTimeout = TimeSpan.FromSeconds(30),
    DataConnectionConnectTimeout = TimeSpan.FromSeconds(30),
    SocketKeepAlive = true
};

using FtpAdapter adapter = new("ftp.example.org", 21, "username", "password", options);
IDirectory directory = adapter.OpenDirectory("/incoming");

The directory must already exist. Keep the adapter alive while using its elements, and dispose it after those operations are complete. Completed read snapshots remain usable after adapter disposal.

Connection Settings

FtpSecurity.None, ExplicitTls, and ImplicitTls select plain FTP, explicit FTPS, and implicit FTPS. The default is None; select a TLS mode explicitly when encryption is required. FTPS and SFTP are different protocols; use SftpAdapter from the SSH adapter library for an SFTP server.

Options also cover active or passive data connections, IP protocol selection, control and data connection timeouts, keep-alive, and command/name encoding.

Normal FTPS server certificate validation is enabled by default. Set AcceptAnyCertificate only for deliberately insecure connections, for example in a controlled test environment.

Persisted Attachment Configurations

FtpAttachConfig exposes the FTP connection parameters as properties. It can be created from a host or from an existing FtpAdapter. Serialized configurations are opened provider-neutrally through AttachConfig.Open:

using System.Text.Json.Nodes;

FtpAttachConfig config = new(adapter)
{
    InitialPath = "/incoming"
};

JsonObject data = config.Serialize();
AttachConfig restored = AttachConfig.Open(data);
using FtpAdapter restoredAdapter = (FtpAdapter) restored.CreateAdapter();
IDirectory restoredDirectory = restoredAdapter.OpenDirectory(restored.InitialPath);

The JSON representation contains a format version and the ftp adapter discriminator. If a password is configured, it is part of the serialized configuration. The shell can protect the complete serialized configuration with its attach --save --password option.

Supported Operations

The adapter supports listing, path lookup, name filtering, stream-based reads, file and directory creation and deletion, recursive copy and move, and local upload and download through the common FileStorageAdapters API.

Files can be transferred to and from other adapters through streams. Directory transfers are recursive. CopyToAsync(destination) places the source inside the destination directory under its existing name; the overload with a name argument selects a different destination name.

Existing content is not overwritten unless overwrite is true. Copying a directory into an existing directory of the same name with overwrite enabled merges the contents and retains unrelated destination files. Cross-adapter moves copy the content before deleting the source and are not atomic.

Paths and Metadata

/ denotes the root exposed by the FTP server. The initial directory is a starting point, not an additional navigation boundary. Relative paths are resolved from the directory context; . and .. are supported, and both / and \ are accepted as logical separators.

Metadata depends on the server's listing and command support. Directory sizes are calculated recursively and can require many server requests. Content types and ETags are returned as null.

Example

With directory opened as shown above:

IFile source = await directory.GetFileAsync("report.txt");
await using Stream content = await source.ReadAsync();

IDirectory output = await directory.CreateDirectoryAsync("processed");
IFile copy = await output.CreateFileAsync("report.txt", content, overwrite: true);
Console.WriteLine(copy.Path);

Streams returned by ReadAsync are owned by the caller and must be disposed. Streams supplied to CreateFileAsync remain owned by the caller and are not disposed by the adapter.

Concurrent access and buffered reads

Client operations on one adapter are serialized. ReadAsync downloads the entire file into temporary local storage before returning a read-only, seekable stream. The returned stream does not hold the adapter connection or its operation gate. Dispose each returned stream to remove its temporary storage. Each stream supports one consumer; do not concurrently read, seek or dispose that same stream.

DisposeAsync rejects new client accesses and waits for the active client access before closing the connection. Dispose waits synchronously for the same result. A copy or recursive transfer consists of several accesses and can fail between steps if its adapter is closed early. Neither copies nor moves are transactions.

Use an exclusively owned client; externally supplied streams must not re-enter the destination adapter from their read or dispose callbacks during an upload. See THREAD-SAFETY-PLAN.md in the source archive for the implementation stage, remaining conflict-handling work and validation status.

Conflict guarantees

Standard FTP cannot atomically create a caller-named file only if absent. The existence check is serialized within one adapter, but other clients can still race it. Do not rely on overwrite:false as a cross-client create-only guarantee.

Product Compatible and additional computed target framework versions.
.NET 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 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 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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
1.0.2 50 10/20/2026
1.0.1 102 9/28/2026