C# Download all files and subdirectories through FTP

General Info

I'm still in the process of learning C#. To help myself out, I'm trying to create a program that will automatically synchronise all of my local projects with a folder on my FTP server. This so that whether I'm at school or at home, I always have the same projects available to me.

I know there are programs like Dropbox that already do this for me, but I figured creating something like that myself will teach me a lot along the way.

The problem

My first step towards my goal was to just download all files, subdirectories and subfiles from my FTP server. I've managed to download all files from a directory with the code below. However, my code only lists the folder names and the files in the main directory. Subfolders and subfiles are never returned and never downloaded. Aside from that, the server returns a 550 error because I'm trying to download the folders as if they are files. I've been on this for 4+ hours now, but I just can't find anything on how to fix these problems and make it work. Therefor I'm hoping you guys will help me out :)

The FtpWebRequest does not have any explicit support for recursive file operations (including downloads). You have to implement the recursion yourself:

List the remote directory

Iterate the entries, downloading files and recusing into subdirectories (listing them again, etc.)

Tricky part is to identify files from subdirectories. There's no way to do that in a portable way with the FtpWebRequest. The FtpWebRequest unfortunately does not support the MLSD command, which is the only portable way to retrieve directory listing with file attributes in FTP protocol. See also Checking if object on FTP server is file or directory.

Your options are:

Do a operation on a file name that is certain to fail for file and succeeds for directories (or vice versa). I.e. you can try to download the "name". If that succeeds, it's a file, if that fails, it's a directory.

You may be lucky and in your specific case, you can tell a file from a directory by a file name (i.e. all your files have an extension, while subdirectories do not)

You use a long directory listing (LIST command = ListDirectoryDetails method) and try to parse a server-specific listing. Many FTP servers use *nix-style listing, where you identify a directory by the d at the very beginning of the entry. But many servers use a different format. The following example uses this approach (assuming the *nix format)

If you want to avoid troubles with parsing the server-specific directory listing formats, use a 3rd party library that supports the MLSD command and/or parsing various LIST listing formats; and recursive downloads.