Dec 252011
 

As I was creating upgrade procedure for few programs of mine I had a need to download file. With progress bar. Most of you can already see a solution: HttpWebRequest in BackgroundWorker.

Base idea is creation of HttpWebRequest, getting it’s response as stream and iterating through all bytes until we read them all. Heart of (DoWork) code is:

var request = (HttpWebRequest)HttpWebRequest.Create(url);
using (var response = (HttpWebResponse)request.GetResponse()) {
    using (var stream = response.GetResponseStream()) {
        using (var bytes = new MemoryStream()) {
            var buffer = new byte[256];
            while (bytes.Length < response.ContentLength) {
                var read = stream.Read(buffer, 0, buffer.Length);
                if (read > 0) {
                    bytes.Write(buffer, 0, read);
                    bcwDownload.ReportProgress((int)(bytes.Length * 100 / len));
                } else {
                    break;
                }
            }
        }
    }
}

Before we send result back to RunWorkerCompleted event we need to get file name that was actually delivered. While this step is optional, I find it especially useful if there are some redirections on web site (e.g. pointing you to newer version of file):

string fileName = response.ResponseUri.Segments[response.ResponseUri.Segments.Length - 1];
e.Result = new DownloadResult(fileName, bytes.ToArray());

P.S. Do notice that DownloadResult is our own class – there is no such class in .NET Framework.

In RunWorkerCompleted we only must save file as such:

var res = (DownloadResult)e.Result;
var file = new FileInfo(res.FileName);
using (var frm = new SaveFileDialog() { FileName = file.Name }) {
    if (frm.ShowDialog(this) == DialogResult.OK) {
        File.WriteAllBytes(frm.FileName, res.Bytes);
        MessageBox.Show(this, "Done.", "Something", MessageBoxButtons.OK, MessageBoxIcon.Information);
    }
}

And with that you have your file downloaded.

Full source code (with all missing parts of code) is available for download.

 Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>