简体   繁体   中英

Resuming download in C# WPF

I'm developing a WPF application which downloads some MSI files which are greater than 100 MB. While downloading, if the internet is disconnected, the currently downloading file has to resume from where the download was interrupted. I used the WebClient and Cookies for downloading the files. The files are not resumed if the internet was disconnected and connected again. I have used the following code. Can anyone suggest me how to achieve the resume process?

using (CookieAwareWebClient client = new CookieAwareWebClient())
{
        client.DownloadProgressChanged += WebClientDownloadProgressChanged;
   client.DownloadFileCompleted += new AsyncCompletedEventHandler(Client_DownloadFileCompleted);      
  client.DownloadFileAsync(url, fileName);
 }

static void WebClientDownloadProgressChanged(object sender, 
DownloadProgressChangedEventArgs e)
    {
        Console.WriteLine("Download status: {0}%.", e.ProgressPercentage);
        Console.WriteLine(e.BytesReceived.ToString());

    }

    static void Client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
    {
        Console.WriteLine("Download finished!");
    }       

}

public class CookieAwareWebClient : WebClient
{
    private readonly CookieContainer m_container = new CookieContainer();

    protected override WebRequest GetWebRequest(Uri address)
    {
        WebRequest request = base.GetWebRequest(address);
        HttpWebRequest webRequest = request as HttpWebRequest;
        if (webRequest != null)
        {
            webRequest.CookieContainer = m_container;
        }
        return request;
    }
}

For resuming the download, you can establish the connection once again und specify the offset of the data to be downloaded. Moreover, you can also request a part of the data to be downloaded.

  // establishing the connection
  HttpWebRequest oHttpWebRequest = (HttpWebRequest) WebRequest.Create ("myHttpAddress");

  #if partialDownload

  // reading the range 1000-2000 of the data
  oHttpWebRequest.AddRange (1000, 2000);
  // creating the file
  FileInfo oFileInfo = new FileInfo ("myFilename");
  FileStream oFileStream = oFileInfo.Create ();

  #else

  // reading after the last received byte
  FileInfo oFileInfo = new FileInfo ("myFilename");
  oHttpWebRequest.AddRange (oFileInfo.Length);
  // opening the file for appending the data
  FileStream oFileStream = File.Open (oFileInfo.FullName, FileMode.Append);

  #endif

  // opening the connection
  HttpWebResponse oHttpWebResponse = (HttpWebResponse) oHttpWebRequest.GetResponse ();
  Stream oReceiveStream = oHttpWebResponse.GetResponseStream ();

  // reading the HTML stream and writing into the file
  byte [] abBuffer = new byte [1000000];
  int iReceived = oReceiveStream.Read (abBuffer, 0, abBuffer.Length);
  while ( iReceived > 0 )
  { 
    oFileStream.Write (abBuffer, 0, iReceived);
    iReceived = oReceiveStream.Read (abBuffer, 0, abBuffer.Length);
  };
  // closing and disposing the resources
  oFileStream     .Close   ();
  oFileStream     .Dispose ();
  oReceiveStream  .Close   ();
  oReceiveStream  .Dispose ();
  oHttpWebResponse.Close   ();
  oHttpWebResponse.Dispose ();

For debugging, you can take a look into the received data by looking into the returned header of the web request. For a partial download you might obtain for example

Content-Range: bytes 1000-2000/1156774
Content-Length: 1001

You obtain the keys of the header from

oHttpWebResponse.Headers.Keys []

and the values from

oHttpWebResponse.Headers []

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM