.netftpfluentftp

Getting all FTP directory/file listings recursively in one call


I'm creating a backup program that backs data up to FTP. To archive effectively, I need to do several file attribute comparisons. Right now, I am using FluentFTP and calling FtpClient.FileExists FtpClient.GetFileSize, and FtpClient.GetModifiedTime per file. This is obviously not very optimal.

If I could download the FTP directory's entire tree structure in a single call along with file attributes, it would improve back-up speed substantially. The alternative is to build a local index, but then I have to make sure it's being updated properly and also account for the possibility of it getting corrupted.

Is there any way to do this other than roll my own solution?


Solution

  • FTP offers these commands to retrieve an information about remote files:

    So you do not have to use FtpClient.GetFileSize and FtpClient.GetModifiedTime per file. Use FtpClient.GetListing per directory. Internally it uses MLSD, if supported by the server. Otherwise it falls back to LIST and tries to parse the listing.


    Some FTP servers (like ProFTPD) do support a non-standard proprietary -R switch to the LIST command that will make them return listing across all subfolders. FluentFTP supports that too (FtpListOption.Recursive). Though note that FluentFTP uses -R with LIST only, while it prefers using MLSD, if the server supports it. So to make sure LIST -R is used, you need to use both FtpListOption.Recursive and FtpListOption.ForceList.

    If your server does not support the -R switch, you have to implement recursion yourself. Or use an FTP client that has API for it.

    For example with my WinSCP .NET assembly, you can use Session.EnumerateRemoteFiles:

    IEnumerable<RemoteFileInfo> allFiles =
        session.EnumerateRemoteFiles("/", null, EnumerationOptions.AllDirectories);