2010-05-06 12 views
27

Il seguente codice è destinato a recuperare un file tramite FTP. Tuttavia, sto ottenendo un errore con esso.FtpWebRequest Download File

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'errore è:

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

Il file sicuramente esiste sulla macchina remota e sono in grado di eseguire questa ftp manualmente (vale a dire non ho i permessi). Qualcuno può dirmi perché potrei avere questo errore?

+1

Trovo wirehark utile per cose come questa. È possibile impostare un filtro per visualizzare il traffico FTP tra la macchina e il server. –

+0

Cosa succede se si imposta UsePassive su false? Non ho mai avuto alcun server che utilizzava la modalità passiva. – Roy

+0

Questo in genere causerebbe un errore di timeout nella mia esperienza in quanto tenta di utilizzare una porta bloccata dal firewall. –

risposta

21

Questo paragrafo dal FptWebRequest class reference potrebbe essere di vostro interesse:

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

E come può aiutare? – SerG

+0

Beh, per me si trattava di trattare con caratteri non ASCII, come un # era nell'URL, devono essere codificati in url. – CularBytes

40

So che questo è un vecchio post, ma io sono l'aggiunta per riferimenti futuri. Ecco una soluzione che ho trovato:

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

Aggiornato basata su ottimo suggerimento di Ilya Kogan

+3

Si noti che è necessario disporre di oggetti IDisposable. Il modo più semplice per farlo è usare la parola chiave 'using'. –

+0

Sei corretto, ho postato questa risposta quando ero piuttosto nuovo in C# –

+9

Se vuoi usare 'WebClient', piuttosto che' FtpWebRequest', puoi usare il suo ['DownloadFile'] (http: // msdn.microsoft.com/en-us/library/system.net.webclient.downloadfile.aspx) metodo, piuttosto che scherzare con un 'FileStream', che potrebbe essere un po 'più semplice. Ci sono alcune cose che WebClient non può fare, però (come usare 'ACTV' piuttosto che' PASV' FTP: 'FtpWebRequest.UsePassive = false;') Il proxy –

2

Ho avuto lo stesso problema!

La mia soluzione era inserire la cartella public_html nell'URL di download.

posizione del file reale sul server: URL

myhost.com/public_html/myimages/image.png

Web:

www.myhost.com/myimages/image.png

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

Dopo questo si può utilizzare la linea di seguito per evitare errori .. (accesso negato ecc.)

request.Proxy = null; 
+0

non è nulla per impostazione predefinita. –

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; 

    } 

Spero che possa aiutare.

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

Il modo più banale per scaricare un file binario da un server FTP utilizzando il framework .NET utilizza 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"); 

Usa FtpWebRequest, solo se avete bisogno di un maggiore controllo, che non lo fa WebClient offerta (come la crittografia TLS/SSL, il monitoraggio dei progressi, ecc.).Un modo semplice è quello basta copiare un flusso di risposta FTP per FileStream utilizzando 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); 
} 

Se avete bisogno di controllare un avanzamento del download, è necessario copiare il contenuto da pezzi te:

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

Per GUI progress (WinForms ProgressBar), vedi:
FtpWebRequest FTP download with ProgressBar

Se volete scaricare tutti i file da una cartella remota, vedere
C# Download all files and subdirectories through FTP.