SSH.NET SFTP Get a list of directories and files recursively

.net, c#, sftp, ssh.net

Solution

This library has some quirks that make this recursive listing tricky because the interaction between the `ChangeDirectory` and `ListDirectory` do not work as you may expect.

The following does not list the files in the /home directory instead it lists the files in the / (root) directory:

sftp.ChangeDirectory("home");
sftp.ListDirectory("").Select (s => s.FullName);

The following does not work and returns a SftpPathNotFoundException:

sftp.ChangeDirectory("home");
sftp.ListDirectory("home").Select (s => s.FullName);

The following is the correct way to list the files in the /home directory

sftp.ChangeDirectory("/");
sftp.ListDirectory("home").Select (s => s.FullName);

This is pretty crazy if you ask me. Setting the default directory with the `ChangeDirectory` method has no effect on the `ListDirectory` method unless you specify a folder in the parameter of this method. Seems like a bug should be written for this.

So when you write your recursive function you'll have to set the default directory once and then change the directory in the `ListDirectory` call as you iterate over the folders. The listing returns an enumerable of SftpFiles. These can then be checked individually for `IsDirectory == true`. Just be aware that the listing also returns the `.` and `..` entries (which are directories). You'll want to skip these if you want to avoid an infinite loop. :-)

EDIT 2/23/2018

I was reviewing some of my old answers and would like to apologize for the answer above and supply the following working code. Note that this example does not require `ChangeDirectory`, since it's using the `Fullname` for the `ListDirectory`:

void Main()
{
    using (var client = new Renci.SshNet.SftpClient("sftp.host.com", "user", "password"))
    {
        var files = new List<String>();
        client.Connect();
        ListDirectory(client, ".", ref files);
        client.Disconnect();
        files.Dump();
    }
}

void ListDirectory(SftpClient client, String dirName, ref List<String> files)
{
    foreach (var entry in client.ListDirectory(dirName))
    {

        if (entry.IsDirectory)
        {
            ListDirectory(client, entry.FullName, ref files);
        }
        else
        {
            files.Add(entry.FullName);
        }
    }
}

Problem

I am using Renci.SshNet library to get a list of files and directories recursively by using SFTP. I can able to connect SFTP site but I am not sure how to get a list of directories and files recursively in C#. I haven't found any useful examples. Has anybody tried this? If so, can you post some sample code about how to get these files and folders recursively. Thanks, Prav

Original source