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

后端 未结 5 1721
不思量自难忘°
不思量自难忘° 2021-02-13 13:50

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 director

5条回答
  •  误落风尘
    2021-02-13 14:26

    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();
            client.Connect();
            ListDirectory(client, ".", ref files);
            client.Disconnect();
            files.Dump();
        }
    }
    
    void ListDirectory(SftpClient client, String dirName, ref List files)
    {
        foreach (var entry in client.ListDirectory(dirName))
        {
    
            if (entry.IsDirectory)
            {
                ListDirectory(client, entry.FullName, ref files);
            }
            else
            {
                files.Add(entry.FullName);
            }
        }
    }
    

提交回复
热议问题