2010-05-06 52 views
27

Mã sau đây nhằm truy xuất tệp qua FTP. Tuy nhiên, tôi nhận được một lỗi với nó.FtpWebRequest Tải xuống Tệp

serverPath = "ftp://x.x.x.x/tmp/myfile.txt"; 

FtpWebRequest request = (FtpWebRequest)WebRequest.Create(serverPath); 

request.KeepAlive = true; 
request.UsePassive = true; 
request.UseBinary = true; 

request.Method = WebRequestMethods.Ftp.DownloadFile;     
request.Credentials = new NetworkCredential(username, password); 

// Read the file from the server & write to destination     
using (FtpWebResponse response = (FtpWebResponse)request.GetResponse()) // Error here 
using (Stream responseStream = response.GetResponseStream()) 
using (StreamReader reader = new StreamReader(responseStream))    
using (StreamWriter destination = new StreamWriter(destinationFile)) 
{ 
    destination.Write(reader.ReadToEnd()); 
    destination.Flush(); 
} 

Lỗi này là:

The remote server returned an error: (550) File unavailable (e.g., file not found, no access)

Các tập tin chắc chắn không tồn tại trên máy từ xa và tôi có thể thực hiện ftp này bằng tay (ví dụ: Tôi có quyền). Bất cứ ai có thể cho tôi biết lý do tại sao tôi có thể nhận được lỗi này?

+1

Tôi tìm thấy Wireshark hữu ích cho những thứ như thế này. Bạn có thể thiết lập bộ lọc để xem lưu lượng truy cập FTP giữa máy của bạn và máy chủ. –

+0

Điều gì sẽ xảy ra nếu bạn đặt UsePassive thành false? Tôi không bao giờ có bất kỳ máy chủ làm việc bằng cách sử dụng chế độ thụ động .. – Roy

+0

Điều đó thường sẽ gây ra một lỗi thời gian trong kinh nghiệm của tôi khi nó cố gắng sử dụng một cổng bị chặn bởi tường lửa. –

Trả lời

21

Đoạn này từ FptWebRequest class reference có thể quan tâm đến bạn:

The URI may be relative or absolute. If the URI is of the form " ftp://contoso.com/%2fpath " (%2f is an escaped '/'), then the URI is absolute, and the current directory is /path. If, however, the URI is of the form " ftp://contoso.com/path ", first the .NET Framework logs into the FTP server (using the user name and password set by the Credentials property), then the current directory is set to /path.

+1

Và nó có thể giúp gì? – SerG

+0

Vâng, đối với tôi, đó là vấn đề đối phó với các ký tự không phải ASCII, như số # nằm trong URL, chúng phải được mã hóa url. – CularBytes

40

Tôi biết đây là một bài viết cũ nhưng tôi thêm vào đây để tham khảo sau này. Đây là một giải pháp mà tôi thấy:

private void DownloadFileFTP() 
    { 
     string inputfilepath = @"C:\Temp\FileName.exe"; 
     string ftphost = "xxx.xx.x.xxx"; 
     string ftpfilepath = "/Updater/Dir1/FileName.exe"; 

     string ftpfullpath = "ftp://" + ftphost + ftpfilepath; 

     using (WebClient request = new WebClient()) 
     { 
      request.Credentials = new NetworkCredential("UserName", "[email protected]"); 
      byte[] fileData = request.DownloadData(ftpfullpath); 

      using (FileStream file = File.Create(inputfilepath)) 
      { 
       file.Write(fileData, 0, fileData.Length); 
       file.Close(); 
      } 
      MessageBox.Show("Download Complete"); 
     } 
    } 

cập nhật dựa trên gợi ý tuyệt vời bởi Ilya Kogan

+3

Lưu ý rằng bạn nên vứt bỏ các đối tượng IDisposable. Cách dễ nhất để làm điều này là sử dụng từ khóa 'using'. –

+0

Bạn chính xác, tôi đã đăng phản hồi này khi tôi còn khá mới đối với C# –

+9

Nếu bạn định sử dụng 'WebClient', thay vì' FtpWebRequest', bạn có thể sử dụng ['DownloadFile'] của nó (http: // Phương thức msdn.microsoft.com/en-us/library/system.net.webclient.downloadfile.aspx), thay vì làm rối tung một 'FileStream', có thể dễ dàng hơn một chút. Có một số điều mà WebClient không thể làm, mặc dù (ví dụ như sử dụng 'ACTV' hơn là 'PASV' FTP:' FtpWebRequest.UsePassive = false; ') –

2

tôi đã cùng một vấn đề!

Giải pháp của tôi là chèn thư mục public_html vào URL tải xuống.

vị trí file Real trên máy chủ: URL

myhost.com/public_html/myimages/image.png

Web:

www.myhost.com/myimages/image.png

0
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(serverPath); 

Sau này bạn có thể sử dụng dòng dưới đây để tránh lỗi .. (truy cập bị từ chối, v.v.)

request.Proxy = null; 
+0

proxy là không có gì theo mặc định. –

1
private static DataTable ReadFTP_CSV() 
    { 
     String ftpserver = "ftp://servername/ImportData/xxxx.csv"; 
     FtpWebRequest reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(ftpserver)); 

     reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword); 
     FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse(); 

     Stream responseStream = response.GetResponseStream(); 

     // use the stream to read file from FTP 
     StreamReader sr = new StreamReader(responseStream); 
     DataTable dt_csvFile = new DataTable(); 

     #region Code 
     //Add Code Here To Loop txt or CSV file 
     #endregion 

     return dt_csvFile; 

    } 

Tôi hy vọng nó có thể giúp bạn.

0
public void download(string remoteFile, string localFile) 
    { 
     private string host = "yourhost"; 
     private string user = "username"; 
     private string pass = "passwd"; 
     private FtpWebRequest ftpRequest = null; 
     private FtpWebResponse ftpResponse = null; 
     private Stream ftpStream = null; 
     private int bufferSize = 2048; 

     try 
     { 
      ftpRequest = (FtpWebRequest)FtpWebRequest.Create(host + "/" + remoteFile); 

      ftpRequest.Credentials = new NetworkCredential(user, pass); 

      ftpRequest.UseBinary = true; 
      ftpRequest.UsePassive = true; 
      ftpRequest.KeepAlive = true; 

      ftpRequest.Method = WebRequestMethods.Ftp.DownloadFile; 
      ftpResponse = (FtpWebResponse)ftpRequest.GetResponse(); 
      ftpStream = ftpResponse.GetResponseStream(); 

      FileStream localFileStream = new FileStream(localFile, FileMode.Create); 

      byte[] byteBuffer = new byte[bufferSize]; 
      int bytesRead = ftpStream.Read(byteBuffer, 0, bufferSize); 

      try 
      { 
       while (bytesRead > 0) 
       { 
        localFileStream.Write(byteBuffer, 0, bytesRead); 
        bytesRead = ftpStream.Read(byteBuffer, 0, bufferSize); 
       } 
      } 

      catch (Exception) { } 

      localFileStream.Close(); 
      ftpStream.Close(); 
      ftpResponse.Close(); 
      ftpRequest = null; 
     } 

     catch (Exception) { } 
     return; 
    } 
4

Cách tầm thường nhất để tải về một tập tin nhị phân từ một máy chủ FTP sử dụng .NET framework đang sử dụng WebClient.DownloadFile:

WebClient client = new WebClient(); 
client.Credentials = new NetworkCredential("username", "password"); 
client.DownloadFile(
    "ftp://ftp.example.com/remote/path/file.zip", @"C:\local\path\file.zip"); 

Sử dụng FtpWebRequest, chỉ khi bạn cần có một kiểm soát tốt hơn, mà không WebClient cung cấp (như mã hóa TLS/SSL, theo dõi tiến độ, v.v.)Cách dễ dàng là chỉ cần sao chép một dòng phản ứng FTP để FileStream sử dụng Stream.CopyTo:

FtpWebRequest request = 
    (FtpWebRequest)WebRequest.Create("ftp://ftp.example.com/remote/path/file.zip"); 
request.Credentials = new NetworkCredential("username", "password"); 
request.Method = WebRequestMethods.Ftp.DownloadFile; 

using (Stream ftpStream = request.GetResponse().GetResponseStream()) 
using (Stream fileStream = File.Create(@"C:\local\path\file.zip")) 
{ 
    ftpStream.CopyTo(fileStream); 
} 

Nếu bạn cần phải theo dõi một tiến trình download, bạn phải sao chép nội dung của khối mình:

FtpWebRequest request = 
    (FtpWebRequest)WebRequest.Create("ftp://ftp.example.com/remote/path/file.zip"); 
request.Credentials = new NetworkCredential("username", "password"); 
request.Method = WebRequestMethods.Ftp.DownloadFile; 

using (Stream ftpStream = request.GetResponse().GetResponseStream()) 
using (Stream fileStream = File.Create(@"C:\local\path\file.zip")) 
{ 
    byte[] buffer = new byte[10240]; 
    int read; 
    while ((read = ftpStream.Read(buffer, 0, buffer.Length)) > 0) 
    { 
     fileStream.Write(buffer, 0, read); 
     Console.WriteLine("Downloaded {0} bytes", fileStream.Position); 
    } 
} 

Đối với GUI tiến bộ (WinForms ProgressBar), xem:
FtpWebRequest FTP download with ProgressBar

Nếu bạn muốn tải về tất cả các tập tin từ một thư mục từ xa, xem
C# Download all files and subdirectories through FTP.