How to Download a File from Internet in C#
By FoxLearn 11/27/2024 8:40:43 AM 14.86K
In a Windows Forms application, file downloads can be enhanced by adding progress updates and keeping the UI responsive. This guide demonstrates how to create a file downloader using WebClient
, featuring a progress bar and multithreaded execution.
How to Download a File from Internet in C#?
Open Visual Studio, then click New Project, then select Visual C# on the left, then Windows and then select Windows Forms Application. Name your project "DownloadDemo" and then click OK
Drag and drop the Label, Button, TextBox, ProgressBar controls from the Visual Toolbox onto your form designer, then design your form as shown below.
For example, Using WebClient
The WebClient
class is older and part of the System.Net
namespace. It’s simple to use but is considered outdated for new projects.
In the Form1_Load
event, initialize the WebClient
and attach event handlers for progress updates and completion notifications:
private void Form1_Load(object sender, EventArgs e) { client = new WebClient(); client.DownloadProgressChanged += Client_DownloadProgressChanged; client.DownloadFileCompleted += Client_DownloadFileCompleted; }
The btnDownload_Click
event starts the download on a separate thread, ensuring the UI remains responsive:
private void btnDownload_Click(object sender, EventArgs e) { //Run download file with multiple thread string url = txtUrl.Text; if (!string.IsNullOrEmpty(url)) { Thread thread = new Thread(() => { Uri uri = new Uri(url); string fileName = System.IO.Path.GetFileName(uri.AbsolutePath); client.DownloadFileAsync(uri, Application.StartupPath + "/" + fileName); }); thread.Start(); } }
The DownloadProgressChanged
event updates the progress bar and label dynamically.
private void Client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e) { //Update progress bar & label Invoke(new MethodInvoker(delegate () { progressBar.Minimum = 0; double receive = double.Parse(e.BytesReceived.ToString()); double total = double.Parse(e.TotalBytesToReceive.ToString()); double percentage = receive / total * 100; lblStatus.Text = $"Downloaded {string.Format("{0:0.##}", percentage)}%"; progressBar.Value = int.Parse(Math.Truncate(percentage).ToString()); })); }
When the download is complete, the DownloadFileCompleted
event shows a message box.
private void Client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e) { MessageBox.Show("Download complete !", "Message", MessageBoxButtons.OK, MessageBoxIcon.Information); }
Below is the form code.
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Net; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace DownloadDemo { public partial class Form1 : Form { public Form1() { InitializeComponent(); } WebClient client; } }
For example, Using HttpClient
The HttpClient
class is part of the System.Net.Http
namespace and is more modern and flexible way to perform asynchronous tasks, including downloading files with progress updates.
HttpClient client; private void Form1_Load(object sender, EventArgs e) { // Initialize HttpClient client = new HttpClient(); }
We use HttpClient.GetAsync()
to start downloading the file, and HttpCompletionOption.ResponseHeadersRead
to ensure that the headers are read immediately, allowing us to start downloading the content as soon as possible.
The btnDownload_Click
method now uses async/await
to download the file asynchronously, which keeps the UI responsive during the download.
private async void btnDownload_Click(object sender, EventArgs e) { // Run download file with multiple thread string url = txtUrl.Text; if (!string.IsNullOrEmpty(url)) { Uri uri = new Uri(url); string fileName = Path.GetFileName(uri.AbsolutePath); string destinationPath = Path.Combine(Application.StartupPath, fileName); // Start the download process in a separate task await DownloadFileAsync(uri, destinationPath); } }
The DownloadFileAsync
method is responsible for reading the file stream, writing it to disk, and reporting progress.
private async Task DownloadFileAsync(Uri uri, string destinationPath) { try { // Start the download process asynchronously var response = await client.GetAsync(uri, HttpCompletionOption.ResponseHeadersRead); // Ensure the request was successful response.EnsureSuccessStatusCode(); var totalBytes = response.Content.Headers.ContentLength ?? 0; var progress = new Progress<double>(value => { // Update progress bar & label Invoke(new MethodInvoker(delegate () { progressBar.Minimum = 0; double percentage = value * 100; lblStatus.Text = $"Downloaded {string.Format("{0:0.##}", percentage)}%"; progressBar.Value = (int)Math.Truncate(percentage); })); }); using (var stream = await response.Content.ReadAsStreamAsync()) { using (var fileStream = new FileStream(destinationPath, FileMode.Create, FileAccess.Write, FileShare.None)) { var buffer = new byte[8192]; long totalRead = 0; int bytesRead; while ((bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length)) > 0) { await fileStream.WriteAsync(buffer, 0, bytesRead); totalRead += bytesRead; var progressPercentage = (double)totalRead / totalBytes; progress.Report(progressPercentage); } } } MessageBox.Show("Download complete!", "Message", MessageBoxButtons.OK, MessageBoxIcon.Information); } catch (Exception ex) { MessageBox.Show($"Error: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
We use a Progress<double>
instance to report the download progress. The progress percentage is calculated based on the total file size (ContentLength
) and the number of bytes read (totalRead
).
The file is saved to the disk using a FileStream
. The data is written in small chunks (buffer size of 8KB) for efficient memory usage.
VIDEO TUTORIAL
- How to update UI from another thread in C#
- How to get CheckedListBox selected values in C#
- How to use Advanced Filter DataGridView in C#
- How to create a Notification Popup in C#
- How to Use Form Load and Button click Event in C#
- How to Link Chart /Graph with Database in C#
- How to Check SQL Server Connection in C#
- How to Generate Serial Key in C#