464 votes

Comment télécharger un fichier à partir d'une URL en C# ?

Quel est le moyen le plus simple de télécharger un fichier à partir d'un chemin URL ?

18 votes

Jetez un coup d'œil à System.Net.WebClient.

3voto

Kiran Shahi Points 4435

D'après mes recherches, j'ai découvert que WebClient.DownloadFileAsync est le meilleur moyen de télécharger un fichier. Il est disponible en System.Net et il prend également en charge l'espace de noms .net core.

Voici l'exemple de code pour télécharger le fichier.

using System;
using System.IO;
using System.Net;
using System.ComponentModel;

public class Program
{
    public static void Main()
    {
        new Program().Download("ftp://localhost/test.zip");
    }
    public void Download(string remoteUri)
    {
        string FilePath = Directory.GetCurrentDirectory() + "/tepdownload/" + Path.GetFileName(remoteUri); // path where download file to be saved, with filename, here I have taken file name from supplied remote url
        using (WebClient client = new WebClient())
        {
            try
            {
                if (!Directory.Exists("tepdownload"))
                {
                    Directory.CreateDirectory("tepdownload");
                }
                Uri uri = new Uri(remoteUri);
                //password username of your file server eg. ftp username and password
                client.Credentials = new NetworkCredential("username", "password");
                //delegate method, which will be called after file download has been complete.
                client.DownloadFileCompleted += new AsyncCompletedEventHandler(Extract);
                //delegate method for progress notification handler.
                client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(ProgessChanged);
                // uri is the remote url where filed needs to be downloaded, and FilePath is the location where file to be saved
                client.DownloadFileAsync(uri, FilePath);
            }
            catch (Exception)
            {
                throw;
            }
        }
    }
    public void Extract(object sender, AsyncCompletedEventArgs e)
    {
        Console.WriteLine("File has been downloaded.");
    }
    public void ProgessChanged(object sender, DownloadProgressChangedEventArgs e)
    {
        Console.WriteLine($"Download status: {e.ProgressPercentage}%.");
    }
}

Avec le code ci-dessus, le fichier sera téléchargé dans tepdownload du répertoire du projet. Veuillez lire le commentaire dans le code pour comprendre ce que le code ci-dessus fait.

3voto

Cryptc Points 196

Dans le cas où vous avez besoin de mettre En-têtes y Cookies pour télécharger un fichier, vous devrez procéder de manière légèrement différente. Voici un exemple exemple ...

// Pass in the HTTPGET URL, Full Path w/Filename, and a populated Cookie Container (optional)
private async Task DownloadFileRequiringHeadersAndCookies(string getUrl, string fullPath, CookieContainer cookieContainer, CancellationToken cancellationToken)
{
    cookieContainer ??= new CookieContainer();  // TODO: FILL ME AND PASS ME IN

    using (var handler = new HttpClientHandler()
    {
        UseCookies = true,
        CookieContainer = cookieContainer, // This will, both, use the cookies passed in, and update/create cookies from the response
        ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true, // use only if it gets angry about the SSL endpoints
        AllowAutoRedirect = true,
    })
    {
        using (var client = new HttpClient(handler))
        {
            SetHeaders(client);

            using (var response = await client.GetAsync(getUrl, cancellationToken))
            {
                if (response.IsSuccessStatusCode)
                {
                    var bytes = await response.Content.ReadAsByteArrayAsync(cancellationToken);
                    await File.WriteAllBytesAsync(fullPath, bytes, cancellationToken); // This overwrites the file
                }
                else
                {
                    // TODO: HANDLE ME
                    throw new FileNotFoundException();
                }
            }
        }
    }
}

Et, pour ajouter les en-têtes dont vous avez besoin avec ceci...

private void SetHeaders(HttpClient client)
{
    // TODO: SET ME
    client.DefaultRequestHeaders.Connection.Add("keep-alive");
    client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) ...");
    client.DefaultRequestHeaders.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9, ...");
    client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip"));
    client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("deflate"));
    client.DefaultRequestHeaders.AcceptLanguage.Add(new StringWithQualityHeaderValue("en-US"));
    client.DefaultRequestHeaders.AcceptLanguage.Add(new StringWithQualityHeaderValue("en", .9));
    ...
}

ASIDE : Vous pouvez remplir le CookieContainer par :

  1. Boucle dans les cookies d'une réponse précédente.
    • Cette réponse peut provenir de HttpAgilityPack, ou de WebClient, ou de Puppeteer (beaucoup d'options).
  2. Entrées manuelles (à partir de valeurs de configuration ou de valeurs codées en dur).

2voto

Kreshnik Points 162

Vous pouvez avoir besoin de connaître l'état et de mettre à jour une barre de progression pendant le téléchargement du fichier ou d'utiliser les informations d'identification avant de faire la demande.

Le voici, un exemple qui couvre ces options. Notation lambda y Interpolation de chaînes de caractères a été utilisé :

using System.Net;
// ...

using (WebClient client = new WebClient()) {
    Uri ur = new Uri("http://remotehost.do/images/img.jpg");

    //client.Credentials = new NetworkCredential("username", "password");
    String credentials = Convert.ToBase64String(Encoding.ASCII.GetBytes("Username" + ":" + "MyNewPassword"));
    client.Headers[HttpRequestHeader.Authorization] = $"Basic {credentials}";

    client.DownloadProgressChanged += (o, e) =>
    {
        Console.WriteLine($"Download status: {e.ProgressPercentage}%.");

        // updating the UI
        Dispatcher.Invoke(() => {
            progressBar.Value = e.ProgressPercentage;
        });
    };

    client.DownloadDataCompleted += (o, e) => 
    {
        Console.WriteLine("Download finished!");
    };

    client.DownloadFileAsync(ur, @"C:\path\newImage.jpg");
}

0 votes

Quelques commentaires sur l'objectif de vos déclarations de code seraient utiles, pour ceux qui ne sont pas familiers avec les opérations asynchrones et les appels inter-filières.

2voto

M22 Points 81
static void Main(string[] args)
        {
            DownloadFileAsync().GetAwaiter();

            Console.WriteLine("File was downloaded");
            Console.Read();
        }

        private static async Task DownloadFileAsync()
        {
            WebClient client = new WebClient();
            await client.DownloadFileTaskAsync(new Uri("http://somesite.com/myfile.txt"), "mytxtFile.txt");
        }

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X