2014-05-16 441 views
23
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服務器複製到我的服務器的本地驅動器。使用SSH.NET庫從SFTP下載文件

以上是我有的代碼,但它不工作。有時候它說文件不存在,但有時我將下載的文件不會在我的本地服務器上,但我需要下載當天上傳到遠程文件夾的任何文件。

有人可以看看有什麼不對嗎?我相信這與流媒體部分有關。除了上傳文件外,我還使用過很多FTP,我使用了之前的一些代碼,並認爲我可以將該過程逆轉,但這不起作用。我使用的代碼是基於這個example

+1

在我的情況下,代碼僅在連接時停止。它說'沒有找到合適的身份驗證方法進行身份驗證。「# – Chirag

回答

24

簡單的工作代碼來下載一個文件SSH.NET庫:

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

要解釋一下,爲什麼您的代碼不起作用:

的第二個參數SftpClient.DownloadFile是一個寫入下載內容的流。

您正在傳入讀取流而不是寫入流。此外,您正在打開的讀取流路徑是遠程路徑,但僅對本地文件操作的類不能使用File類。

就放棄File.OpenRead行並使用以前File.OpenWrite調用的結果,而不是(你是不是用在所有的現在):

Stream file1 = File.OpenWrite(localFileName); 

sftp.DownloadFile(file.FullName, file1); 

甚至更​​好,使用File.Create要放棄以前的本地文件可能具有的內容。

我不確定您的localFileName應該保存完整路徑,還是隻保存文件名。所以,你可能需要添加路徑也一樣,如果有必要(與sDir結合localFileName?)

+3

'var file1 = File.OpenWrite(localFileName); sftp.DownloadFile(file.FullName,file1);' –

+0

@ freedomn-m謝謝。糾正。 –

0

沒有你提供任何具體的錯誤消息,很難給出具體的建議。

但是,我正在使用相同的例子,並獲取File.OpenWrite上的權限異常 - 使用localFileName變量,因爲使用Path.GetFile指向的位置顯然不具有打開文件的權限> C :\ ProgramFiles \ IIS(Express)\ filename.doc

我發現使用System.IO.Path.GetFileName不正確,請改用System.IO.Path.GetFullPath,指向以「C: \ ...「

同時在FileExplorer中打開您的解決方案,併爲該文件或持有該文件的任何文件夾授予asp.net權限。我能夠在那個時候下載我的文件。

10

雖然示例工程,它不是正確的方式來處理流...

你需要確保文件的關閉/使用條款.. 此外,加試/與流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); 
        } 
      } 

     } 
    } 
2

我的@Merak Marey's Code版本。我正在檢查文件是否已經存在以及.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(); 

     } 
+1

如果你想添加一些基於擴展名的FileInfo fi,你可以簡單地做:'string ext = fi.Extension;'和一個開關。因爲'LOVE-LETTER-FOR-YOU.TXT.vbs'將是一個誤報。或'Path.GetExtension(myFilePath);' –

+0

要小心,您正在檢查文件名是否包含「.TXT」,並且取決於服務器操作系統,您可能會得到「.txt」(小寫)..將小寫remoteFilename變量並將其用於條件,而不是file.Name ... –

+0

更好:if(!file.Name.ToLower()。EndsWith(「。txt」)) –