Jak pobrać plik z adresu URL w C #?


350

Jaki jest prosty sposób pobierania pliku ze ścieżki URL?


13
Spójrz na System.Net.WebClient
seanb

Odpowiedzi:


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

24
Najlepsze rozwiązanie w historii, ale chciałbym dodać 1 ważny wiersz „client.Credentials = new NetworkCredential („ UserName ”,„ Password ”);”
Deweloper

3
Powitalny efekt uboczny: Ta metoda obsługuje również pliki lokalne jako pierwszy parametr
oo_dev

Dokument MSDN wspomniał teraz o użyciu HttpClient zamiast tego: docs.microsoft.com/en-us/dotnet/api/…
StormsEngineering

Chociaż myślę, że WebClient wydaje się być znacznie prostszym i prostszym rozwiązaniem.
StormsEngineering

1
@ copa017: Lub niebezpieczny, jeśli na przykład adres URL jest dostarczany przez użytkownika, a kod C # działa na serwerze WWW.
Heinzi,

177

Uwzględnij tę przestrzeń nazw

using System.Net;

Pobierz asynchronicznie i umieść pasek postępu, aby pokazać status pobierania w samym wątku interfejsu użytkownika

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
Pytanie dotyczy najprostszego sposobu. Komplikowanie nie jest najprostsze.
Zagadnienie

75
Większość osób woli pasek postępu podczas pobierania. Właśnie napisałem najprostszy sposób, aby to zrobić. To może nie być odpowiedź, ale spełnia wymagania Stackoverflow. To ma komuś pomóc.
Sayka

3
Jest to tak samo proste jak inna odpowiedź, jeśli po prostu pominiesz pasek postępu. Ta odpowiedź obejmuje także przestrzeń nazw i używa asynchronizacji dla operacji we / wy. Również pytanie nie wymaga najprostszego sposobu, tylko prosty sposób. :)
Josh

Myślę, że lepiej byłoby udzielić 2 odpowiedzi jednej prostej i jednej z paskiem postępu
Jesse de gans

@Jenedegans Istnieje już odpowiedź, która pokazuje, jak po prostu pobierać bez paska postępu. Dlatego napisałem odpowiedź, która pomaga w asynchronicznym pobieraniu i implementacji
paska

75

Użyj 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
Witamy w SO! Zasadniczo nie jest dobrym pomysłem zamieszczanie odpowiedzi niskiej jakości na istniejące i stare pytania, które już mają bardzo pozytywne odpowiedzi.
ThiefMaster

28
Znalazłem odpowiedź z komentarza seanb, ale naprawdę wolę tę odpowiedź „niskiej jakości” od innych. Jest kompletny (za pomocą instrukcji), zwięzły i łatwy do zrozumienia. Bycie starym pytaniem nie ma znaczenia, IMHO.
Josh

21
Uważa jednak, że odpowiedź na temat używania jest znacznie lepsza, ponieważ uważam, że WebClient powinien zostać usunięty po użyciu. Umieszczenie go w środku za pomocą zapewnia jego utylizację.
Ricardo Polo Jaramillo,

5
Nie ma to nic wspólnego z utylizacją w tym przykładzie kodu ... Instrukcja using pokazuje po prostu przestrzeń nazw do użycia, nie, że WebClient używa do używania do usuwania ...
cdie

17

Ukończ klasę, aby pobrać plik podczas drukowania statusu na konsolę.

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

Stosowanie:

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

1
Czy możesz wyjaśnić, dlaczego używasz SemaphoreSlimw tym kontekście?
mmushtaq

10

Spróbuj użyć tego:

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

gdzie plik zostanie zapisany?
IB

Plik zostanie zapisany w lokalizacji, w której znajduje się plik wykonywalny. Jeśli chcesz uzyskać pełną ścieżkę, użyj pełnej ścieżki wraz z plikiem (który jest nazwą pliku, który chcesz pobrać)
Surendra Shrestha


8

Sprawdź połączenie sieciowe, GetIsNetworkAvailable()aby uniknąć tworzenia pustych plików, gdy nie jest ono podłączone do sieci.

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

Sugerowałbym, aby nie używać, GetIsNetworkAvailable()ponieważ z mojego doświadczenia zwraca zbyt wiele fałszywych trafień.
Cherona

O ile nie jesteś w sieci komputerowej, takiej jak LAN, GetIsNetworkAvailable()zawsze wróci poprawnie. W takim przypadku możesz użyć System.Net.WebClient().OpenRead(Uri)metody, aby sprawdzić, czy zwraca po otrzymaniu domyślnego adresu URL. Zobacz WebClient.OpenRead ()
haZya

2

Poniższy kod zawiera logikę pobierania pliku o oryginalnej nazwie

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

Konieczne może być sprawdzenie stanu i aktualizacja paska postępu podczas pobierania pliku lub użycie poświadczeń przed wysłaniem żądania.

Oto przykład obejmujący te opcje. Zastosowano notację lambda i interpolację ciągów :

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

Z moich badań wynika, że WebClient.DownloadFileAsyncto najlepszy sposób na pobranie pliku. Jest dostępny w System.Netprzestrzeni nazw i obsługuje również rdzeń .net.

Oto przykładowy kod do pobrania pliku.

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

Z powyższym kodem plik zostanie pobrany w tepdownloadfolderze katalogu projektu. Przeczytaj komentarz w kodzie, aby zrozumieć, co robi powyższy kod.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.