先看 ETag:
The ETag response-header field provides the current value of the entity tag for the requested variant. (引自RFC2616 14.19 ETag)
简单点说 ETag 就是一个标识当前请求内容的字符串,当请求的资源发生变化后,对应的 ETag 也会变化。好了,最简单的办法是第一次请求时,把响应头中的 ETag 存下来,下次请求时做比较。代码如下:
string newEtag = GetEtag(response);
// tempFileName指已经下载到本地的部分文件内容
// tempFileInfoName指保存了Etag内容的临时文件
if (File.Exists(tempFileName) && File.Exists(tempFileInfoName))
{
string oldEtag = File.ReadAllText(tempFileInfoName);
if (!string.IsNullOrEmpty(oldEtag) && !string.IsNullOrEmpty(newEtag) && newEtag == oldEtag)
{
// Etag没有变化,可以断点续传
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;
}
再来看看 Last-Modified:
The Last-Modified entity-header field indicates the date and time at which the origin server believes the variant was last modified. (引自RFC2616 14.29 Last-Modified)
Last-Modified 就是所请求的资源在服务器上的最后一次修改时间。使用方法和 ETag 大体相同。
个人感觉使用 ETag 和 Last-Modified 中的任何一个都能达到我们的目的。但是你也可以两个都用,做 double check,谁知道web服务器的实现是不是严格遵循了 HTTP 协议!
保存中间结果
这里主要就是用 C# 进行文件操作。大体思路是如果有未下载完的文件,就把新下载的字节添加到文件的末尾,不再啰嗦,有兴趣的同学请直接看 demo 代码。
验证文件
在断点续传的过程中,我们以 byte 为单位下载、合并文件,如果整个过程中稍有没有处理好的异常,可能最后得到的文件就和源文件不太一样。因此最好是能够对下载好的文件进行一次校验。可这也是最难、最不容易实现的。因为它需要服务器端的支持,比如服务器端在提供一个可下载文件的同时提供该文件的 MD5 hash。当然,如果服务器端也是我们自己创建的,我们就可以去实现它。但我们又怎么能够要求现存的 web 服务器都提供这样的功能呢!
Demo 下载
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持ASPKU。
注:相关教程知识阅读请移步到c#教程频道。










