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

352

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

vbroto
la source
13
Jetez un œil à System.Net.WebClient
seanb

Réponses:

475
using (var client = new WebClient())
{
    client.DownloadFile("http://example.com/file/song/a.mpeg", "a.mpeg");
}
Raj Kumar
la source
24
La meilleure solution de tous les temps mais j'aimerais ajouter 1 ligne importante 'client.Credentials = new NetworkCredential ("UserName", "Password");'
Développeur
3
Un effet secondaire bienvenu: cette méthode prend également en charge les fichiers locaux en tant que 1er paramètre
oo_dev
Le document MSDN a mentionné d'utiliser HttpClient maintenant à la place: docs.microsoft.com/en-us/dotnet/api/…
StormsEngineering
Bien que je pense que WebClient semble être une solution beaucoup plus directe et simple.
StormsEngineering
1
@ copa017: Ou dangereux, si, par exemple, l'URL est fournie par l'utilisateur et que le code C # s'exécute sur un serveur Web.
Heinzi
177

Inclure cet espace de noms

using System.Net;

Téléchargez de manière asynchrone et mettez une barre de progression pour afficher l'état du téléchargement dans le thread d'interface utilisateur lui-même

private void BtnDownload_Click(object sender, RoutedEventArgs e)
{
    using (WebClient wc = new WebClient())
    {
        wc.DownloadProgressChanged += wc_DownloadProgressChanged;
        wc.DownloadFileAsync (
            // Param1 = Link of file
            new System.Uri("http://www.sayka.com/downloads/front_view.jpg"),
            // Param2 = Path to save
            "D:\\Images\\front_view.jpg"
        );
    }
}
// Event to track the progress
void wc_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
    progressBar.Value = e.ProgressPercentage;
}
Sayka
la source
14
La question demande le moyen le plus simple. Rendre plus compliqué n'est pas le plus simple.
Énigmativité du
75
La plupart des gens préfèrent une barre de progression lors du téléchargement. Je viens donc d'écrire la façon la plus simple de le faire. Ce n'est peut-être pas la réponse, mais cela répond à l'exigence de Stackoverflow. C'est pour aider quelqu'un.
Sayka
3
C'est tout aussi simple que l'autre réponse si vous omettez simplement la barre de progression. Cette réponse inclut également l'espace de noms et utilise async pour les E / S. De plus, la question ne demande pas le moyen le plus simple, juste un moyen simple. :)
Josh
Je pense que donner 2 réponses une simple et une avec une barre de progression serait mieux
Jesse de gans
@Jessedegans Il existe déjà une réponse qui montre comment télécharger simplement sans barre de progression. C'est pourquoi j'ai écrit une réponse qui aide au téléchargement asynchrone et à la mise en œuvre de la
barre de
76

Utilisation System.Net.WebClient.DownloadFile:

string remoteUri = "http://www.contoso.com/library/homepage/images/";
string fileName = "ms-banner.gif", myStringWebResource = null;

// Create a new WebClient instance.
using (WebClient myWebClient = new WebClient())
{
    myStringWebResource = remoteUri + fileName;
    // Download the Web resource and save it into the current filesystem folder.
    myWebClient.DownloadFile(myStringWebResource, fileName);        
}
vbroto
la source
42
using System.Net;

WebClient webClient = new WebClient();
webClient.DownloadFile("http://mysite.com/myfile.txt", @"c:\myfile.txt");
petrzjunior
la source
33
Bienvenue chez SO! Généralement, ce n'est pas une bonne idée de publier une réponse de faible qualité à une question existante et ancienne qui a déjà des réponses très appréciées.
ThiefMaster
28
J'ai trouvé ma réponse dans le commentaire de seanb, mais je préfère vraiment cette réponse "de mauvaise qualité" aux autres. Il est complet (à l'aide d'une déclaration), concis et facile à comprendre. Être une vieille question est hors de propos, à mon humble avis.
Josh
21
Mais il pense que la réponse avec Using est bien meilleure, car je pense que le WebClient devrait être éliminé après utilisation. Le mettre à l'intérieur à l'aide garantit qu'il est éliminé.
Ricardo Polo Jaramillo
5
Cela n'a rien à voir avec l'élimination dans cet exemple de code ... L'instruction using ici montre simplement l'espace de noms à utiliser, non que WebClient utilise pour être
éliminé
17

Cours complet pour télécharger un fichier pendant l'impression de l'état sur la console.

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

class FileDownloader
{
    private readonly string _url;
    private readonly string _fullPathWhereToSave;
    private bool _result = false;
    private readonly SemaphoreSlim _semaphore = new SemaphoreSlim(0);

    public FileDownloader(string url, string fullPathWhereToSave)
    {
        if (string.IsNullOrEmpty(url)) throw new ArgumentNullException("url");
        if (string.IsNullOrEmpty(fullPathWhereToSave)) throw new ArgumentNullException("fullPathWhereToSave");

        this._url = url;
        this._fullPathWhereToSave = fullPathWhereToSave;
    }

    public bool StartDownload(int timeout)
    {
        try
        {
            System.IO.Directory.CreateDirectory(Path.GetDirectoryName(_fullPathWhereToSave));

            if (File.Exists(_fullPathWhereToSave))
            {
                File.Delete(_fullPathWhereToSave);
            }
            using (WebClient client = new WebClient())
            {
                var ur = new Uri(_url);
                // client.Credentials = new NetworkCredential("username", "password");
                client.DownloadProgressChanged += WebClientDownloadProgressChanged;
                client.DownloadFileCompleted += WebClientDownloadCompleted;
                Console.WriteLine(@"Downloading file:");
                client.DownloadFileAsync(ur, _fullPathWhereToSave);
                _semaphore.Wait(timeout);
                return _result && File.Exists(_fullPathWhereToSave);
            }
        }
        catch (Exception e)
        {
            Console.WriteLine("Was not able to download file!");
            Console.Write(e);
            return false;
        }
        finally
        {
            this._semaphore.Dispose();
        }
    }

    private void WebClientDownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
    {
        Console.Write("\r     -->    {0}%.", e.ProgressPercentage);
    }

    private void WebClientDownloadCompleted(object sender, AsyncCompletedEventArgs args)
    {
        _result = !args.Cancelled;
        if (!_result)
        {
            Console.Write(args.Error.ToString());
        }
        Console.WriteLine(Environment.NewLine + "Download finished!");
        _semaphore.Release();
    }

    public static bool DownloadFile(string url, string fullPathWhereToSave, int timeoutInMilliSec)
    {
        return new FileDownloader(url, fullPathWhereToSave).StartDownload(timeoutInMilliSec);
    }
}

Usage:

static void Main(string[] args)
{
    var success = FileDownloader.DownloadFile(fileUrl, fullPathWhereToSave, timeoutInMilliSec);
    Console.WriteLine("Done  - success: " + success);
    Console.ReadLine();
}
Jonas_Hess
la source
1
Pourriez-vous expliquer pourquoi utilisez-vous SemaphoreSlimdans ce contexte?
mmushtaq
10

Essayez d'utiliser ceci:

private void downloadFile(string url)
{
     string file = System.IO.Path.GetFileName(url);
     WebClient cln = new WebClient();
     cln.DownloadFile(url, file);
}
Surendra Shrestha
la source
où le fichier sera enregistré?
IB
Le fichier sera enregistré à l'emplacement où se trouve le fichier exécutable. Si vous voulez un chemin complet, utilisez le chemin complet avec le fichier (qui est le nom de fichier de l'élément à télécharger)
Surendra Shrestha
9

Vous pouvez également utiliser la méthode DownloadFileAsync dans la classe WebClient. Il télécharge dans un fichier local la ressource avec l'URI spécifié. De plus, cette méthode ne bloque pas le thread appelant.

Échantillon:

    webClient.DownloadFileAsync(new Uri("http://www.example.com/file/test.jpg"), "test.jpg");

Pour plus d'informations:

http://csharpexamples.com/download-files-synchronous-asynchronous-url-c/

turgay
la source
8

Recherchez une connexion réseau à l'aide de GetIsNetworkAvailable()pour éviter de créer des fichiers vides lorsque vous n'êtes pas connecté à un réseau.

if (System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable())
{
    using (System.Net.WebClient client = new System.Net.WebClient())
    {                        
          client.DownloadFileAsync(new Uri("http://www.examplesite.com/test.txt"),
          "D:\\test.txt");
    }                  
}
haZya
la source
Je suggérerais de ne pas utiliser GetIsNetworkAvailable()car, selon mon expérience, renvoie trop de faux positifs.
Cherona
Sauf si vous êtes dans un réseau informatique tel qu'un LAN, GetIsNetworkAvailable()reviendrait toujours correctement. Dans un tel cas, vous pouvez utiliser la System.Net.WebClient().OpenRead(Uri)méthode pour voir si elle retourne lorsqu'elle reçoit une URL par défaut. Voir WebClient.OpenRead ()
haZya
2

Le code ci-dessous contient la logique de téléchargement du fichier avec le nom d'origine

private string DownloadFile(string url)
    {

        HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
        string filename = "";
        string destinationpath = Environment;
        if (!Directory.Exists(destinationpath))
        {
            Directory.CreateDirectory(destinationpath);
        }
        using (HttpWebResponse response = (HttpWebResponse)request.GetResponseAsync().Result)
        {
            string path = response.Headers["Content-Disposition"];
            if (string.IsNullOrWhiteSpace(path))
            {
                var uri = new Uri(url);
                filename = Path.GetFileName(uri.LocalPath);
            }
            else
            {
                ContentDisposition contentDisposition = new ContentDisposition(path);
                filename = contentDisposition.FileName;

            }

            var responseStream = response.GetResponseStream();
            using (var fileStream = File.Create(System.IO.Path.Combine(destinationpath, filename)))
            {
                responseStream.CopyTo(fileStream);
            }
        }

        return Path.Combine(destinationpath, filename);
    }
Darshit Gandhi
la source
1

Vous devrez peut-être connaître l'état et mettre à jour une barre de progression pendant le téléchargement du fichier ou utiliser des informations d'identification avant de faire la demande.

Le voici, un exemple qui couvre ces options. La notation lambda et l' interpolation de chaînes ont été utilisées:

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");
}
Kreshnik
la source
1

Selon mes recherches, j'ai trouvé que WebClient.DownloadFileAsyncc'était la meilleure façon de télécharger un fichier. Il est disponible dans l' System.Netespace de noms et prend également en charge le noyau .net.

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 le tepdownloaddossier du répertoire du projet. Veuillez lire les commentaires dans le code pour comprendre ce que fait le code ci-dessus.

Kiran Shahi
la source