使用SSH.NET库从SFTP下载文件

string host = @"ftphost"; string username = "user"; string password = "********"; string localFileName = System.IO.Path.GetFileName(@"localfilename"); string remoteDirectory = "/export/"; using (var sftp = new SftpClient(host, username, password)) { sftp.Connect(); var files = sftp.ListDirectory(remoteDirectory); foreach (var file in files) { if (!file.Name.StartsWith(".")) { string remoteFileName = file.Name; if (file.LastWriteTime.Date == DateTime.Today) Console.WriteLine(file.FullName); File.OpenWrite(localFileName); string sDir = @"localpath"; Stream file1 = File.OpenRead(remoteDirectory + file.Name); sftp.DownloadFile(remoteDirectory, file1); } } } 

我使用SSH.NET( Renci.SshNet )库来处理SFTP服务器。 我需要做的是根据今天的日期从SFTP服务器上的特定文件夹中获取文件。 然后将这些文件从SFTP服务器复制到我的服务器的本地驱动器。

以上是我的代码,但它不起作用。 有时它说文件不存在但有时我将下载的文件不会在我的本地服务器上,但我需要下载当天上传到远程文件夹的任何文件。

有人可以看看,看看有什么问题吗? 我认为它与流部分有关。 除了上传文件之外,我还使用过FTP,我之前使用过的代码,并认为我可以改变过程,但这样做无效。 我使用的代码基于这个例子 。

使用SSH.NET库下载文件的简单工作代码是:

 using (Stream fileStream = File.Create(@"C:\target\local\path\file.zip")) { sftp.DownloadFile("/source/remote/path/file.zip", fileStream); } 

另请参阅使用C#中的SSH.NET SFTP下载目录 。


要解释一下,为什么你的代码不起作用:

SftpClient.DownloadFile的第二个参数是用于将下载内容写入的流。

您正在传入读取流而不是写入流。 此外,您打开读取流的路径是一个远程路径,对于仅在本地文件上运行的File类不起作用。

只需丢弃File.OpenRead行并使用以前的File.OpenWrite调用的结果(您现在根本不使用):

 Stream file1 = File.OpenWrite(localFileName); sftp.DownloadFile(file.FullName, file1); 

或者甚至更好,使用File.Create丢弃本地文件可能具有的任何先前内容。

我不确定你的localFileName是否应该保存完整路径,或者只是文件名。 因此,如果需要,您可能还需要添加路径(将localFileNamesDir结合使用?)

虽然该示例有效,但它不是处理流的正确方法……

您需要确保使用using子句关闭文件/流。另外,添加try / catch来处理IO错误…

  public void DownloadAll() { string host = @"sftp.domain.com"; string username = "myusername"; string password = "mypassword"; string remoteDirectory = "/RemotePath/"; string localDirectory = @"C:\LocalDriveFolder\Downloaded\"; using (var sftp = new SftpClient(host, username, password)) { sftp.Connect(); var files = sftp.ListDirectory(remoteDirectory); foreach (var file in files) { string remoteFileName = file.Name; if ((!file.Name.StartsWith(".")) && ((file.LastWriteTime.Date == DateTime.Today)) using (Stream file1 = File.OpenWrite(localDirectory + remoteFileName)) { sftp.DownloadFile(remoteDirectory + remoteFileName, file1); } } } } 

我的版本@Merak Marey的代码。 我正在检查文件是否已存在以及.txt和其他文件的不同下载目录

  static void DownloadAll() { string host = "xxx.xxx.xxx.xxx"; string username = "@@@"; string password = "123";string remoteDirectory = "/IN/"; string finalDir = ""; string localDirectory = @"C:\filesDN\"; string localDirectoryZip = @"C:\filesDN\ZIP\"; using (var sftp = new SftpClient(host, username, password)) { Console.WriteLine("Connecting to " + host + " as " + username); sftp.Connect(); Console.WriteLine("Connected!"); var files = sftp.ListDirectory(remoteDirectory); foreach (var file in files) { string remoteFileName = file.Name; if ((!file.Name.StartsWith(".")) && ((file.LastWriteTime.Date == DateTime.Today))) { if (!file.Name.Contains(".TXT")) { finalDir = localDirectoryZip; } else { finalDir = localDirectory; } if (File.Exists(finalDir + file.Name)) { Console.WriteLine("File " + file.Name + " Exists"); }else{ Console.WriteLine("Downloading file: " + file.Name); using (Stream file1 = File.OpenWrite(finalDir + remoteFileName)) { sftp.DownloadFile(remoteDirectory + remoteFileName, file1); } } } } Console.ReadLine(); } 

如果没有您提供任何特定的错误消息,很难给出具体的建议。

但是,我使用相同的示例并在File.OpenWrite上获取权限exception – 使用localFileName变量,因为使用Path.GetFile指向一个显然没有打开文件权限的位置> C:\ ProgramFiles \ IIS(快递)\ filename.doc

我发现使用System.IO.Path.GetFileName不正确,请改用System.IO.Path.GetFullPath,指向以“C:\ …”开头的文件

还可以在FileExplorer中打开您的解决方案,并为该文件或包含该文件的任何文件夹授予asp.net权限。 那时我能够下载我的文件。