2010-05-06 27 views
27

El siguiente código está destinado a recuperar un archivo a través de FTP. Sin embargo, estoy recibiendo un error con eso.FtpWebRequest Descargar archivo

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

El error es:

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

El archivo sin duda existe en la máquina remota y yo soy capaz de realizar esta ftp manualmente (es decir, no tengo permisos). ¿Alguien puede decirme por qué podría estar recibiendo este error?

+1

Encuentro wireshark útil para cosas como esta. Puede configurar un filtro para ver el tráfico FTP entre su máquina y el servidor. –

+0

¿Qué ocurre si configura UsePassive en falso? Nunca obtuve ningún servidor que trabaje usando el modo pasivo. – Roy

+0

Eso generalmente causaría un error de tiempo de espera en mi experiencia ya que intenta usar un puerto bloqueado por el firewall. –

Respuesta

21

Este párrafo de la FptWebRequest class reference podría ser de su interés:

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

¿Y cómo puede ayudar? – SerG

+0

Bueno, para mí era una cuestión de tratar con caracteres que no son ASCII, como un # estaba en la URL, tienen que estar codificados en la URL. – CularBytes

40

Sé que esto es una entrada antigua, pero estoy añadiendo aquí para referencia futura. Aquí es una solución que he encontrado:

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

actualizados basados ​​en un excelente sugerencia de Ilya Kogan

+3

Tenga en cuenta que debe deshacerse de objetos IDisposable. La forma más fácil de hacerlo es usar la palabra clave 'using'. –

+0

Tiene razón, publiqué esta respuesta cuando era bastante nuevo en C# –

+9

Si va a utilizar 'WebClient', en lugar de' FtpWebRequest', podría usar su ['DownloadFile'] (http: // msdn.microsoft.com/en-us/library/system.net.webclient.downloadfile.aspx) método, en lugar de jugar con un 'FileStream', que podría ser un poco más fácil. Sin embargo, hay algunas cosas que WebClient no puede hacer (como usar 'ACTV' en lugar de' PASV' FTP: 'FtpWebRequest.UsePassive = false;') –

2

que tenían el mismo problema!

Mi solución fue insertar la carpeta public_html en la URL de descarga.

ubicación del archivo real en el servidor: URL

myhost.com/public_html/myimages/image.png

Web:

www.myhost.com/myimages/image.png

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

Después de esto, puede utilizar la línea de abajo para evitar el error .. (acceso denegado, etc.)

request.Proxy = null; 
+0

proxy no es nada por defecto. –

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; 

    } 

espero que le puede ayudar.

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

La forma más trivial para descargar un archivo binario desde un servidor FTP utilizando el framework .NET está utilizando 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"); 

Uso FtpWebRequest, sólo si es necesario un mayor control, que no lo hace WebClient oferta (como cifrado TLS/SSL, control de progreso, etc.).forma fácil es simplemente copiar una secuencia de respuesta FTP para FileStream usando 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); 
} 

Si usted necesita para controlar un progreso de la descarga, usted tiene que copiar el contenido de trozos usted mismo:

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

Por GUI progreso (WinForms ProgressBar), ver:
FtpWebRequest FTP download with ProgressBar

Si quiere descargar todos los archivos de una carpeta remota, consulte
C# Download all files and subdirectories through FTP.