2014-05-16 15 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); 
     } 
    } 
} 

Tôi đang sử dụng thư viện SSH.NET (Renci.SshNet) để làm việc với máy chủ SFTP. Những gì tôi cần làm là lấy các tập tin từ một thư mục cụ thể trên máy chủ SFTP dựa trên ngày hôm nay. Sau đó sao chép các tệp đó từ máy chủ SFTP sang ổ đĩa cục bộ máy chủ của tôi.Tải xuống tệp từ SFTP có thư viện SSH.NET

Trên đây là mã tôi có nhưng nó không hoạt động. Đôi khi nó nói tập tin không tồn tại nhưng đôi khi các tập tin tôi sẽ được tải về sẽ không được trên các máy chủ địa phương của tôi nhưng tôi cần phải tải về bất cứ tập tin được tải lên thư mục từ xa cho ngày hôm đó.

Ai đó có thể xem và xem có gì sai không? Tôi tin rằng nó có cái gì đó để làm với phần dòng. Tôi đã làm việc với FTP nhiều bên cạnh việc tải lên các tập tin mà tôi đã lấy một số mã trước đó tôi đã có và nghĩ rằng tôi có thể đảo ngược quá trình nhưng điều đó không hoạt động. Mã tôi đã sử dụng dựa trên số này là example.

+1

Trong trường hợp mã của tôi chỉ dừng ở thời gian kết nối. Nó nói 'Không có phương thức xác thực thích hợp được tìm thấy để xác thực.' – Chirag

Trả lời

24

Mã làm việc đơn giản để tải về một tập tin với thư viện SSH.NET là:

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

Để giải thích, tại sao mã của bạn không hoạt động:

Tham số thứ hai của SftpClient.DownloadFile là luồng để ghi nội dung đã tải xuống.

Bạn đang chuyển sang luồng đọc thay vì viết luồng. Và hơn nữa con đường bạn đang mở đọc luồng là một đường dẫn từ xa, những gì không thể làm việc với lớp File chỉ hoạt động trên các tệp cục bộ.

Chỉ cần loại bỏ các dòng File.OpenRead và sử dụng kết quả của trước File.OpenWrite cuộc gọi thay vì (mà bạn không sử dụng ở tất cả bây giờ):

Stream file1 = File.OpenWrite(localFileName); 

sftp.DownloadFile(file.FullName, file1); 

Hoặc thậm chí tốt hơn, sử dụng File.Create để loại bỏ bất kỳ trước nội dung mà tệp cục bộ có thể có.

Tôi không chắc liệu localFileName của bạn có được phép giữ đường dẫn đầy đủ hay chỉ tên tệp. Vì vậy, bạn cũng có thể cần phải thêm đường dẫn, nếu cần (kết hợp localFileName với sDir?)

+3

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

+0

@ freedomn-m Cảm ơn. Đã sửa. –

0

Nếu bạn không cung cấp bất kỳ thông báo lỗi cụ thể nào, thật khó đưa ra đề xuất cụ thể.

Tuy nhiên, tôi đã sử dụng cùng một ví dụ và đã nhận được ngoại lệ quyền trên File.OpenWrite - sử dụng biến localFileName, vì sử dụng Path.GetFile trỏ đến vị trí rõ ràng sẽ không có quyền mở tệp> C : \ ProgramFiles \ IIS (Express) \ filename.doc

Tôi thấy rằng việc sử dụng System.IO.Path.GetFileName không đúng, sử dụng System.IO.Path.GetFullPath thay vào đó, trỏ đến tệp của bạn bắt đầu bằng "C: \ ... "

Cũng mở giải pháp của bạn trong FileExplorer và cấp quyền cho asp.net cho tệp hoặc bất kỳ thư mục nào chứa tệp. Tôi đã có thể tải xuống tệp của mình tại thời điểm đó.

10

Trong khi ví dụ làm việc, không phải là cách đúng của nó để xử lý các con suối ...

Bạn cần phải đảm bảo sự đóng cửa của các tập tin/suối với sử dụng khoản .. Ngoài ra, thêm try/bắt để xử lý các lỗi 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

Phiên bản @Merak Marey của tôi. Tôi đang kiểm tra xem các tệp đã tồn tại chưa và các thư mục tải xuống khác nhau cho tệp .txt và các tệp khác

 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

Nếu bạn muốn thêm một cái gì đó dựa trên sử dụng extention FileInfo fi, bạn có thể chỉ cần làm: 'string ext = fi.Extension;' Và một công tắc. Bởi vì 'LOVE-LETTER-FOR-YOU.TXT.vbs' sẽ là một kết quả dương tính giả. hoặc 'Path.GetExtension (myFilePath);' –

+0

hãy cẩn thận, bạn đang kiểm tra xem tên tệp có chứa ".TXT" hay không và tùy thuộc vào Hệ điều hành Máy chủ, bạn có thể nhận được ".txt" (chữ thường) .. sẽ là một ý tưởng tốt để viết hoa từ xaFilename biến và sử dụng nó cho các điều kiện quá thay vì file.Name ... –

+0

Tốt hơn: if (! file.Name.ToLower(). EndsWith (". txt")) –

Các vấn đề liên quan