The .NET blog

How to: Download a file from the Internet with C#

March 16, 2009

With .NET, working with remote files are very easy. From the System.Net namespace, we get several classes which comes in handy for doing just that. For instance, downloading a file to your computer can be accomplished with a few lines of code, using the WebClient class:

try
{
	WebClient webClient = new WebClient();
	webClient.DownloadFile("http://www.google.com/intl/en_ALL/images/logo.gif", @"c:\google_logo.gif");
}
catch(Exception ex)
{
	Console.WriteLine("Could not download file: " + ex.Message);
}

Besides the exception handling, downloading a file, in this case an image, is a two-line job. However, by doing it like this, we will be blocking the application completely while downloading the file. If you have to download larger files than a simple logo, you should definitely do it asynchronously. Fortunately for us, the WebClient class supports this right out of the box. But hey, wouldn’t it be cool if we could somehow see the status of the download in progress? No problem, WebClient can do that too. Here’s a complete example:

using System;
using System.Text;
using System.Net;
using System.ComponentModel;

namespace WebClientDemo
{
	class Program
	{
		static void Main(string[] args)
		{
			try
			{
				WebClient webClient = new WebClient();
				webClient.DownloadFileCompleted += new AsyncCompletedEventHandler(webClient_DownloadFileCompleted);
				webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(webClient_DownloadProgressChanged);
				webClient.DownloadFileAsync(new Uri("http://upload.wikimedia.org/wikipedia/en/2/2e/STS-95_Florida_From_Space.jpg"), @"c:\STS-95_Florida_From_Space.jpg");
				Console.ReadKey();
			}
			catch(Exception ex)
			{
				Console.WriteLine("Could not download file: " + ex.Message);
			}
		}

		static void webClient_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
		{
			Console.WriteLine(String.Format("{0} of {1} bytes downloaded ({2}% done)", e.BytesReceived, e.TotalBytesToReceive, e.ProgressPercentage));
		}

		static void webClient_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
		{
			if(e.Error == null)
				Console.WriteLine("All done downloading the file!");
			else
				Console.WriteLine("Could not download file: " + e.Error.Message);
		}
	}
}

We’re downloading a large image from Wikipedia, and as you will see, progress is written to the console. You can obviously fine tune this a bit – for instance, you might want to limit how often progress is written out, but besides that, it’s working pretty decent, and with a pretty limited amount of code. This is a console application, so there’s not that much need for doing stuff asynchronously, but for a WinForms application, doing stuff like this on a separate thread can be really important. If not for a more responsive UI, then at least for being able to report progress while downloading.

If you want direct access to the data being downloaded, without saving to a file first, you should have a look at the DownloadData() method, which returns a byte array, or the DownloadString() method, which downloads the file and returns a string representation of the content (mostly usable for plaintext files, obviously). Both have an asynchronous version too. Enjoy :)

Filed under: ASP.NET, C# — admin @ 10:14 pm



© net-tutorials.com 2006 - 2010