在C#中使用SSH.NET SFTP下载目录

我正在使用Renci.SSH和C#从Windows机器连接到我的Unix服务器。 当目录内容只是文件时,我的代码按预期工作,但如果目录包含文件夹,我会得到这个

Renci.SshNet.Common.SshException:’失败’

这是我的代码,如何更新此代码以下载目录(如果存在)

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(); } } } 

BeginDownloadFile下载文件 。 您无法使用它来下载文件夹。 为此,您需要逐个下载包含的文件。

以下示例使用同步下载( DownloadFile而不是BeginDownloadFile )以简化操作。 毕竟,无论如何,您正在等待异步下载完成。 要实现具有同步下载的进度条,请参阅使用SSH.NET在ProgressBar中显示文件下载的进度 。

 public static void DownloadDirectory( SftpClient sftpClient, string sourceRemotePath, string destLocalPath) { Directory.CreateDirectory(destLocalPath); IEnumerable 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); } } } } }