Come scaricare un file da un URL in C #?


352

Qual è un modo semplice per scaricare un file da un percorso URL?


13
Dai

Risposte:


475
using (var client = new WebClient())
{
    client.DownloadFile("http://example.com/file/song/a.mpeg", "a.mpeg");
}

24
La migliore soluzione di sempre, ma vorrei aggiungere 1 riga importante 'client.Credentials = new NetworkCredential ("UserName", "Password");'
Sviluppatore

3
Un effetto collaterale positivo: questo metodo supporta anche i file locali come primo parametro
oo_dev il

Il documento MSDN ha menzionato invece di utilizzare HttpClient ora: docs.microsoft.com/en-us/dotnet/api/…
StormsEngineering

Anche se penso che WebClient sembra una soluzione molto più semplice e diretta.
StormsEngineering,

1
@ copa017: O pericoloso, se, ad esempio, l'URL viene fornito dall'utente e il codice C # viene eseguito su un server Web.
Heinzi,

177

Includi questo spazio dei nomi

using System.Net;

Scarica in modo asincrono e inserisci una ProgressBar per mostrare lo stato del download all'interno dell'interfaccia utente stessa

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

14
La domanda chiede il modo più semplice. Rendere più complicato non è renderlo il più semplice.
Enigmativity

75
La maggior parte delle persone preferisce una barra di avanzamento durante il download. Quindi ho appena scritto il modo più semplice per farlo. Questa potrebbe non essere la risposta ma soddisfa i requisiti di StackOverflow. Questo è per aiutare qualcuno.
Sayka,

3
Questa è semplice come l'altra risposta se si esce dalla barra di avanzamento. Questa risposta include anche lo spazio dei nomi e utilizza asincrono per l'I / O. Inoltre la domanda non richiede il modo più semplice, ma solo un modo semplice. :)
Josh,

Penso che dare 2 risposte una semplice e una con una barra di avanzamento sarebbe meglio
Jesse de gans

@Jessedegans C'è già una risposta che mostra come scaricare semplicemente senza una barra di avanzamento. Ecco perché ho scritto una risposta che aiuta con il download asincrono e l'implementazione della
barra di

76

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

42
using System.Net;

WebClient webClient = new WebClient();
webClient.DownloadFile("http://mysite.com/myfile.txt", @"c:\myfile.txt");

33
Benvenuti in SO! Generalmente non è una buona idea pubblicare una risposta di bassa qualità a una domanda esistente e vecchia che ha già risposte altamente votate.
ThiefMaster,

28
Ho trovato la mia risposta dal commento di Seanb, ma in realtà preferisco questa risposta "di bassa qualità" rispetto alle altre. È completo (usando la dichiarazione), conciso e facile da capire. Essere una vecchia domanda è irrilevante, IMHO.
Josh, il

21
Ma pensa che la risposta con Using sia molto meglio, perché, penso che WebClient dovrebbe essere eliminato dopo l'uso. Metterlo all'interno usando assicura che sia smaltito.
Ricardo Polo Jaramillo,

5
Non ha nulla a che fare con smaltire in questo esempio di codice ... L'istruzione using qui mostra solo lo spazio dei nomi da usare, no che WebClient è usato per essere smaltito ...
cdie

17

Classe completa per scaricare un file durante la stampa dello stato sulla 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);
    }
}

Uso:

static void Main(string[] args)
{
    var success = FileDownloader.DownloadFile(fileUrl, fullPathWhereToSave, timeoutInMilliSec);
    Console.WriteLine("Done  - success: " + success);
    Console.ReadLine();
}

1
Per favore, potresti spiegare perché stai usando SemaphoreSlimin questo contesto?
mmushtaq,

10

Prova a usare questo:

private void downloadFile(string url)
{
     string file = System.IO.Path.GetFileName(url);
     WebClient cln = new WebClient();
     cln.DownloadFile(url, file);
}

dove verrà salvato il file?
IB

Il file verrà salvato nella posizione in cui si trova il file eseguibile. Se si desidera il percorso completo, utilizzare il percorso completo insieme al file (che è il nome file dell'elemento da scaricare)
Surendra Shrestha,


8

Verificare la presenza di una connessione di rete GetIsNetworkAvailable()per evitare di creare file vuoti quando non si è connessi a una rete.

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

Suggerirei di non usare GetIsNetworkAvailable()poiché, nella mia esperienza, restituisce troppi falsi positivi.
Cherona,

A meno che non ci si trovi in ​​una rete di computer come una LAN, GetIsNetworkAvailable()ritornerebbe sempre correttamente. In tal caso puoi usare il System.Net.WebClient().OpenRead(Uri)metodo per vedere se ritorna quando ti viene dato un url predefinito. Vedi WebClient.OpenRead ()
haZya il

2

Il codice seguente contiene la logica per il file di download con il nome originale

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

1

Potrebbe essere necessario conoscere lo stato e aggiornare una ProgressBar durante il download del file o utilizzare le credenziali prima di effettuare la richiesta.

Eccolo qui, un esempio che copre queste opzioni. Sono state usate la notazione lambda e l' interpolazione di stringhe :

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

1

Secondo la mia ricerca ho scoperto che WebClient.DownloadFileAsyncè il modo migliore per scaricare il file. È disponibile nello System.Netspazio dei nomi e supporta anche il core .net.

Ecco il codice di esempio per scaricare il file.

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

Con il codice sopra riportato il file verrà scaricato nella tepdownloadcartella della directory del progetto. Si prega di leggere il commento nel codice per capire cosa fa il codice sopra.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.