C # File Download breakpoint continuation

Source: Internet
Author: User
Tags md5 hash ranges

Note that the continuation of the breakpoint mentioned in this article refers specifically to the continuation of the breakpoint in the HTTP protocol. This article focuses on ideas and key codes, please refer to the demo included with this article for more details.

Working principle

Some request/response headers are defined in the HTTP protocol, which are combined to use these header information. We can request only a subset of the data from one file in an HTTP request. So we can save the downloaded data, the next time we just request the remaining data, when all the data are downloaded to the local and then complete the merge work.

The HTTP protocol states that the range of the request data can be specified through the range header in the HTTP request, and the range header is simple to use, as long as the following format is specified:

range:bytes=500-999

It means that only the NO. 500 to No. 999 of the target file is requested 500 bytes.

For example, I have a bytes size file that needs to be downloaded, without specifying a Range header on the first request, to download the entire file. However, after downloading the No. 499 byte, the download is canceled. Then the next time you request to download the same file, you only need to download the NO. 500 byte to the NO. 999 byte of data. The principle looks very simple, but we need to consider the following questions:

1. Does all Web servers support the Range header?
2. There may be a long interval between requests, what if the files on the server change?
3. How do I save some of the downloaded data and related information?
4. How do we verify that the file is exactly the same as the source file when we have the byte operation to spell the original size?

Here we take these questions to explore some of the details of the continuation of the breakpoint.

Check server-side support for breakpoint onward transmission

When the server responds to our request, it indicates in the response header whether or not to accept a portion of the data requested for a resource, via Accept-ranges. But there seems to be a small trap where different servers may return different values to indicate that they can accept requests for some of the resources. Seemingly unified approach is that when the server does not support the request part of the data, will return to Accept-ranges:none, we just have to determine whether the return value is equal to none on the line. The code is as follows:

650) this.width=650; "src="/img/fz.gif "alt=" Copy Code "style=" Margin:0px;padding:0px;border:none; "/>

private static bool Isacceptranges (WebResponse res) {if (res). headers["accept-ranges"] = null) {string s = Res.        headers["Accept-ranges"];        if (s = = "None") {return false; }} return true;

650) this.width=650; "src="/img/fz.gif "alt=" Copy Code "style=" Margin:0px;padding:0px;border:none; "/>

Check server-side files for changes

When we download a portion of a file, it may be downloaded in a moment, or it may take some time to download it, or it may never be downloaded again ...
The question here is how to determine the file on the server or the one half of the file that was downloaded at the moment. If the file on the server has been updated, it will need to be downloaded from the beginning anyway. The continuation of a breakpoint only makes sense if the file on the server has not changed.
For this problem, the HTTP response header gives us a different choice. Both ETag and last-modified can accomplish the task.

Look at the ETag first:

The ETag response-header field provides the current value of the entity tag for the requested variant. (Quoted from RFC2616 14.19 ETag)
Simply put, the etag is a string that identifies the contents of the current request, and when the requested resource changes, the corresponding etag changes. Well, the simplest way is to save the ETag in the response header on the first request and compare it on the next request. The code is as follows:

650) this.width=650; "src="/img/fz.gif "alt=" Copy Code "style=" Margin:0px;padding:0px;border:none; "/>

String newetag = getetag (response);// tempfilename refers to portions of the file that have been downloaded to the local content//  Tempfileinfoname refers to a temporary file that holds the contents of the ETag if  (file.exists (tempfilename)  && file.exists ( Tempfileinfoname)) {    string oldetag = file.readalltext (tempFileInfoName);     if  (!string. IsNullOrEmpty (Oldetag)  && !string. IsNullOrEmpty (Newetag)  && newetag == oldetag)     {     // etag no change, you can continue to resume         resumeDowload =  true;    }}else{    if  (!string. IsNullOrEmpty (Newetag))     {         File.writealltext (Tempfileinfoname, newetag);     }}private static string  getetag (webresponse res) {    if  (res. headers["ETag"] != null)     {        return res. headers["ETag"];    }    return null;}

650) this.width=650; "src="/img/fz.gif "alt=" Copy Code "style=" Margin:0px;padding:0px;border:none; "/>

Look again at last-modified:

The Last-modified entity-header field indicates the date and time at which the origin server believes the variant is last Modified. (Quoted from RFC2616 14.29 last-modified)
Last-modified is the last time the requested resource was modified on the server. The method of use is roughly the same as the ETag.

Personally feel that using the ETag and any one of the last-modified can achieve our goal. But you can also use both, do double check, who knows the implementation of the Web server is not strictly follow the HTTP protocol!

Save Intermediate results

The main thing here is to use C # for file manipulation. The general idea is that if there are not downloaded files, the new downloaded bytes added to the end of the file, no longer verbose, interested students please directly see the demo code.

Validating files

In the process of the continuation of the breakpoint, we download and merge the file in Byte, if there is a slight exception in the process, the final file may not be the same as the source file. It is therefore better to be able to check the downloaded files once. But this is also the hardest and least easy to achieve. Because it requires server-side support, such as the server side to provide a downloadable file while providing the MD5 hash of the file. Of course, if the server side is also created by ourselves, we can implement it. But how can we ask the existing Web server to provide such a function!


C # File Download breakpoint continuation

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.