Downloading a directory using SSH.NET SFTP in C#
BeginDownloadFile
downloads a file. You cannot use it to download a folder. For that you need to download contained files one by one.
The following example uses synchronous download (DownloadFile
instead of BeginDownloadFile
) for simplicity. After all, you are synchronously waiting for asynchronous download to complete anyway. To implement a progress bar with synchronous download, see Displaying progress of file download in a ProgressBar with SSH.NET.
public static void DownloadDirectory(
SftpClient sftpClient, string sourceRemotePath, string destLocalPath)
{
Directory.CreateDirectory(destLocalPath);
IEnumerable<SftpFile> files = sftpClient.ListDirectory(sourceRemotePath);
foreach (SftpFile file in files)
{
if ((file.Name != ".") && (file.Name != ".."))
{
string sourceFilePath = sourceRemotePath + "/" + file.Name;
string destFilePath = Path.Combine(destLocalPath, file.Name);
if (file.IsDirectory)
{
DownloadDirectory(sftpClient, sourceFilePath, destFilePath);
}
else
{
using (Stream fileStream = File.Create(destFilePath))
{
sftpClient.DownloadFile(sourceFilePath, fileStream);
}
}
}
}
}
Related videos on Youtube
BandaidMan
Updated on September 15, 2022Comments
-
BandaidMan over 1 year
I am using Renci.SSH and C# to connect to my Unix server from a Windows machine. My code works as expected when the directory contents are only files, but if the directory contains a folder, I get this
Renci.SshNet.Common.SshException: 'Failure'
This is my code, how can I update this to also download a directory (if exists)
private static void DownloadFile(string arc, string username, string password) { string fullpath; string fp; var options = new ProgressBarOptions { ProgressCharacter = '.', ProgressBarOnBottom = true }; using (var sftp = new SftpClient(Host, username, password)) { sftp.Connect(); fp = RemoteDir + "/" + arc; if (sftp.Exists(fp)) fullpath = fp; else fullpath = SecondaryRemoteDir + d + "/" + arc; if (sftp.Exists(fullpath)) { var files = sftp.ListDirectory(fullpath); foreach (var file in files) { if (file.Name.ToLower().Substring(0, 1) != ".") { Console.WriteLine("Downloading file from the server..."); Console.WriteLine(); using (var pbar = new ProgressBar(100, "Downloading " + file.Name + "....", options)) { SftpFileAttributes att = sftp.GetAttributes(fullpath + "/" + file.Name); var fileSize = att.Size; var ms = new MemoryStream(); IAsyncResult asyncr = sftp.BeginDownloadFile(fullpath + "/" + file.Name, ms); SftpDownloadAsyncResult sftpAsyncr = (SftpDownloadAsyncResult)asyncr; int lastpct = 0; while (!sftpAsyncr.IsCompleted) { int pct = (int)((long)sftpAsyncr.DownloadedBytes / fileSize) * 100; if (pct > lastpct) for (int i = 1; i < pct - lastpct; i++) pbar.Tick(); } sftp.EndDownloadFile(asyncr); Console.WriteLine("Writing File to disk..."); Console.WriteLine(); string localFilePath = "C:\" + file.Name; var fs = new FileStream(localFilePath, FileMode.Create, FileAccess.Write); ms.WriteTo(fs); fs.Close(); ms.Close(); } } } } else { Console.WriteLine("The arc " + arc + " does not exist"); Console.WriteLine(); Console.WriteLine("Please press any key to close this window"); Console.ReadKey(); } } }