Як завантажити файл з URL-адреси на C #?


352

Який простий спосіб завантаження файлу з URL-адреси?


13
Погляньте на System.Net.WebClient
seanb

Відповіді:


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

24
Найкраще рішення коли-небудь, але я хотів би додати 1 важливий рядок 'client.Credentials = новий NetworkCredential ("UserName", "Password"); "
Розробник

3
Вітальний побічний ефект: Цей метод також підтримує локальні файли як 1-й параметр
oo_dev

Доктор MSDN згадав про використання HttpClient зараз: docs.microsoft.com/en-us/dotnet/api/…
StormsEngineering

Хоча я думаю, що WebClient здається набагато більш простим та простим рішенням.
StormsEngineering

1
@ copa017: Або небезпечний, якщо, наприклад, URL надається користувачем і код C # працює на веб-сервері.
Хайнці

177

Включіть цей простір імен

using System.Net;

Завантажте асинхронно і поставте ProgressBar, щоб показати статус завантаження в потоці інтерфейсу користувача

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
Питання задає найпростіший спосіб. Складніше - це не робить його найпростішим.
Енігмативність

75
Більшість людей віддають перевагу панелі прогресу під час завантаження. Тому я просто написав найпростіший спосіб зробити це. Це може бути не відповіддю, але воно відповідає вимозі Stackoverflow. Тобто допомогти комусь.
Сайка

3
Це так само просто, як і інша відповідь, якщо ви просто залишите смужку прогресу. Ця відповідь також включає в себе простір імен і використовує асинхронізацію для вводу-виводу. Також питання не задає найпростіший спосіб, а простий спосіб. :)
Джош

Я думаю, що краще відповісти на 2 відповіді на одну просту та одну із смугою прогресу
Jesse de gans

@Jessedegans Вже є відповідь, яка показує, як просто завантажити без панелі прогресу. Ось чому я написав відповідь, яка допомагає при асинхронному завантаженні та реалізації
панелі

76

Використання 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
Ласкаво просимо до SO! Як правило, не годиться розміщувати неякісну відповідь на існуюче і старе питання, на яке вже є високооцінені відповіді.
ThiefMaster

28
Я знайшов свою відповідь з коментаря seanb, але справді я віддаю перевагу цій "низькоякісній" відповіді над іншими. Це повне (за допомогою висловлювання), стисло і легко зрозуміти. Бути старим питанням не має значення, ІМХО.
Джош

21
Але я думаю, що відповідь із використанням набагато краща, тому що, я думаю, WebClient слід утилізувати після використання. Поміщення його всередину забезпечує його утилізацію.
Рікардо Поло Джарамілло

5
Це не має нічого спільного з розпорядженням у цьому прикладі коду ... Тут використовується оператор просто показує простір імен для використання, ні те, що WebClient використовує для використання для розпорядження ...
cdie

17

Повний клас для завантаження файлу, друкуючи стан консолі.

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

Використання:

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

1
Скажіть, будь ласка, для чого ви використовуєте SemaphoreSlimв цьому контексті?
mmushtaq

10

Спробуйте скористатися цим:

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

де файл буде збережено?
IB

Файл буде збережено у тому місці, де знаходиться виконуваний файл. Якщо ви хочете повний шлях, тоді використовуйте повний шлях разом з файлом (який є назвою файлу для завантаження)
Surendra

9

Також ви можете використовувати метод DownloadFileAsync у класі WebClient. Він завантажує в локальний файл ресурс із вказаним URI. Також цей метод не блокує викликову нитку.

Зразок:

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

Для отримання додаткової інформації:

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


8

Перевірте мережеве з'єднання за допомогою GetIsNetworkAvailable()уникнення створення порожніх файлів, коли вони не підключені до мережі.

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

Я б запропонував не використовувати, GetIsNetworkAvailable()як, на мій досвід, повертає занадто багато помилкових позитивних результатів.
Черона

Якщо ви не знаходитесь в комп'ютерній мережі, наприклад, локальній мережі, GetIsNetworkAvailable()завжди будете правильно повертатися. У такому випадку ви можете скористатися System.Net.WebClient().OpenRead(Uri)методом, щоб побачити, чи повертається він, коли надається URL за замовчуванням. Дивіться WebClient.OpenRead ()
haZya

2

Нижче коду міститься логіка для завантаження файлу з оригінальним іменем

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

Можливо, вам потрібно буде знати стан та оновити ProgressBar під час завантаження файлу або використовувати облікові дані, перш ніж робити запит.

Ось він, приклад, який охоплює ці параметри. Застосовується лямбда-позначення та рядкова інтерполяція :

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

Згідно з моїм дослідженням, я виявив, що WebClient.DownloadFileAsyncце найкращий спосіб завантажити файл. Він доступний у System.Netпросторі імен, а також підтримує .net core.

Ось зразок коду для завантаження файлу.

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

З наведеним вище кодом файл буде завантажений у tepdownloadпапку каталогу проекту. Будь ласка, прочитайте коментар у коді, щоб зрозуміти, що робити вище коду.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.