web-dev-qa-db-fra.com

FtpWebRequest Télécharger le fichier

Le code suivant est destiné à récupérer un fichier via FTP. Cependant, je reçois une erreur avec cela.

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'erreur est:

Le serveur distant a renvoyé une erreur: (550) Fichier non disponible (par exemple, fichier introuvable, aucun accès).

Le fichier existe bel et bien sur la machine distante et je peux effectuer ce ftp manuellement (c’est-à-dire que j’ai les permissions). Quelqu'un peut-il me dire pourquoi je risque de recevoir cette erreur?

31
Paul Michaels

Ce paragraphe de la référence de la classe FptWebRequest pourrait vous intéresser:

L'URI peut être relatif ou absolu . Si l'URI est de la forme " ftp://contoso.com/%2fpath " (% 2f est un '/' échappé), l'URI est alors absolue, et le répertoire en cours est /chemin. Si, toutefois, l'URI est du type forme " ftp://contoso.com/path ", d'abord le .NET Framework se connecte au FTP serveur (en utilisant le nom d'utilisateur et le mot de passe définis par la propriété Credentials ), puis le répertoire en cours est défini sur/chemin.

23
Frank Bollack

Je sais que ceci est un ancien post, mais j'ajoute ici pour référence future. Voici une solution que j'ai trouvée:

    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", "P@55w0rd");
            byte[] fileData = request.DownloadData(ftpfullpath);

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

Mise à jour sur la base d'une excellente suggestion d'Ilya Kogan

45
Mark Kram

Moyen le plus simple

Le moyen le plus simple de télécharger un fichier binaire depuis un serveur FTP à l'aide de .NET Framework consiste à utiliser 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");

Options avancées

Utilisez FtpWebRequest , uniquement si vous avez besoin d’un contrôle plus important que WebClient n’offre pas (comme le cryptage TLS/SSL, la surveillance de la progression, etc.). Le moyen le plus simple est simplement de copier un flux de réponse FTP dans FileStream en utilisant 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);
}

Suivi des progrès

Si vous devez surveiller la progression du téléchargement, vous devez copier le contenu vous-même par morceaux:

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

Pour connaître la progression de l'interface graphique (WinForms ProgressBar), voir:
Téléchargement FTP FtpWebRequest avec ProgressBar


Dossier de téléchargement

Si vous souhaitez télécharger tous les fichiers d’un dossier distant, voir
C # Télécharger tous les fichiers et sous-répertoires via FTP .

14
Martin Prikryl

J'ai eu le même problème!

Ma solution consistait à insérer le dossier public_html dans l'URL de téléchargement.

Emplacement réel du fichier sur le serveur:

myhost.com/public_html/myimages/image.png

URL Web:

www.myhost.com/myimages/image.png

2
Tom
    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;

    }

J'espère que cela peut vous aider.

2
Alingar Nwe Lay
   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;
    }
0
MORFEE89
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(serverPath);

Ensuite, vous pouvez utiliser la ligne ci-dessous pour éviter les erreurs .. (accès refusé, etc.)

request.Proxy = null;
0
user1770848