亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C# > 正文

C# 文件下載之斷點續傳實現代碼

2019-10-29 21:15:55
字體:
來源:轉載
供稿:網友

注意,本文所說的斷點續傳特指 HTTP 協議中的斷點續傳。本文主要聊聊思路和關鍵代碼,更多細節請參考本文附帶的 demo。

工作原理

HTTP 協議中定義了一些請求/響應頭,通過組合使用這些頭信息。我們可以在一次 HTTP 請求中只請求一個文件中的一部分數據。這樣我們就可以把已經下載的數據存起來,下次只用請求剩余的數據即可,當全部數據都下載到本地后再完成合并工作。

HTTP 協議指出,可以通過 HTTP 請求中的 Range 頭指定請求數據的范圍,Range 頭的使用也很簡單,只要指定下面的格式就可以了:

Range: bytes=500-999

它的意思是,只請求目標文件的第 500 到第 999 這 500 個字節。

比如我有一個1000 bytes 大小的文件需要下載,第一次請求時不用指定 Range 頭,表示下載整個文件。但在下載完第 499 個字節后,下載被取消了。那么在下一次請求下載同一個文件時,只需要下載第 500 個字節至第 999 個字節的數據就可以了。原理看上去很簡單,但我們需要考慮下面幾個問題:

1.是不是所有的 web 服務器都支持 Range 頭?

2.多次請求之間可能會間隔很長的時間,服務器上的文件發生了變化怎么辦?

3.如何保存下載的部分數據和相關信息?

4.當我們通過字節操作把一個文件拼成原始大小后,如何驗證它和源文件一模一樣?

下面我們就帶著這些問題去探究斷點續傳的一些細節。

檢查服務器端對斷點續傳的支持

在服務器響應我們的請求時,會在響應頭中通過 Accept-Ranges 指明是否接受請求一個資源的一部分數據。但這里似乎有個小小的陷阱,就是不同的服務器可能返回不同的值來指明自己能夠接受部分資源的請求。貌似比較統一的方法是,當服務器不支持請求部分數據時,都會返回 Accept-Ranges: none,我們只要判斷這個返回值是不是等于 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;}

檢查服務器端文件是否變化

當我們下載了一個文件的一部分之后,可能馬上就會接著下載,也可能會過一段時間再下載,也可能永遠不會再接著下載了…
這里的問題是,當下次要接著下載時,如何確定服務器上的文件還是當初下載了一半的那個文件。如果服務器上的文件已經更新了,那無論如何都需要重新從頭開始下載。只有在服務器上的文件沒有發生變化的情況下,斷點續傳才有意義。
對于這個問題,HTTP 響應頭為我們提供了不同的選擇。ETag 和 Last-Modified 都能完成任務。

先看 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 下載

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。


注:相關教程知識閱讀請移步到c#教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
九九热最新视频//这里只有精品| 国产精品91久久久久久| 色七七影院综合| 7777精品久久久久久| 国产精品久久久久久久久久久久久久| 中文字幕精品av| 国产精品丝袜白浆摸在线| 国产精品视频资源| 91精品国产综合久久香蕉| 色黄久久久久久| 亚洲欧洲成视频免费观看| 国产一区二区三区直播精品电影| 欧美电影在线观看网站| 欧美激情欧美狂野欧美精品| 黄色成人av网| 欧美激情亚洲精品| 亚洲国产美女久久久久| 亚洲欧美在线免费| 日韩欧美在线中文字幕| 日韩美女av在线| 久久久免费观看| 久久亚洲成人精品| 国产欧美va欧美va香蕉在| 国产精品人人做人人爽| 欧洲美女免费图片一区| 欧美一级片久久久久久久| 久久久久中文字幕| 欧美性猛交xxxx乱大交蜜桃| 国产精品v片在线观看不卡| 日韩免费视频在线观看| 亚洲二区在线播放视频| 亚洲一区二区日本| 久久夜精品va视频免费观看| 亚洲最大av网| 欧美视频一区二区三区…| 高跟丝袜一区二区三区| 日韩美女免费视频| 欧美一级高清免费播放| 亚洲的天堂在线中文字幕| 日本韩国欧美精品大片卡二| 亚洲精品福利在线观看| 日韩亚洲综合在线| 国外成人在线播放| 九九视频直播综合网| 日韩精品黄色网| 国产一区二区三区在线看| 日韩在线视频线视频免费网站| 精品女同一区二区三区在线播放| 国产主播喷水一区二区| 国产精品第三页| 亚洲国产精品va在线看黑人| 亚洲精品免费一区二区三区| 亚洲高清免费观看高清完整版| 精品成人乱色一区二区| 久久国产精品久久久久久| 91久久在线播放| 日韩中文字幕视频| 国产精品人成电影在线观看| 91色在线观看| 国产精品夜色7777狼人| 国产性猛交xxxx免费看久久| 国产aⅴ夜夜欢一区二区三区| 日本欧美一二三区| 韩国一区二区电影| 国产精品高潮视频| 高清日韩电视剧大全免费播放在线观看| 欧美性感美女h网站在线观看免费| 亚洲成人久久一区| 国产日本欧美一区二区三区| 久热精品视频在线观看一区| 97免费中文视频在线观看| 久久久免费精品| 精品一区精品二区| 九九精品在线观看| 欧美高清在线播放| 91亚洲va在线va天堂va国| 国产91九色视频| 国产午夜精品视频| 国产精品欧美亚洲777777| 日韩中文字在线| 欧美尤物巨大精品爽| 亚洲一区亚洲二区亚洲三区| 久久99青青精品免费观看| 欧美成人黄色小视频| 国产在线久久久| 亚洲天堂久久av| 91av中文字幕| 韩剧1988在线观看免费完整版| 中文字幕精品一区久久久久| 亚洲九九九在线观看| 国产一区二区三区直播精品电影| 国产成人免费av电影| 国产视频久久久久久久| 美女av一区二区三区| 日韩在线观看免费全集电视剧网站| 久久久免费电影| 中文字幕久精品免费视频| 91亚洲国产成人精品性色| 久久国产一区二区三区| 欧美在线观看www| 久久久久亚洲精品国产| 国产精品一区二区电影| 亚洲91精品在线| 欧美成人免费va影院高清| 亚洲免费精彩视频| 欧美激情亚洲自拍| 亚洲国内高清视频| 久久999免费视频| 国产精品免费视频久久久| 欧美日韩国产专区| 91精品国产精品| 亚洲精品福利在线| 欧美色视频日本高清在线观看| 欧美日韩在线视频首页| 色悠悠久久88| 欧美电影在线观看完整版| 色婷婷**av毛片一区| 日韩中文字幕在线| 伊人久久五月天| 中文字幕日韩欧美精品在线观看| 久久香蕉国产线看观看av| 黑人巨大精品欧美一区二区一视频| 精品久久久久久久久久ntr影视| 久久亚洲精品一区| 久久在线精品视频| 国产精品99久久久久久久久久久久| 一本色道久久88精品综合| 亚洲美女中文字幕| 日韩精品视频在线播放| 久久久久久久999精品视频| 亚洲精品国产精品久久清纯直播| 日韩av在线直播| 国产精品视频99| 亚洲午夜色婷婷在线| 国产成人av网址| 欧美性感美女h网站在线观看免费| 亚洲一区二区三区在线视频| 中文字幕久久久| 国产精品高精视频免费| 久久中文精品视频| 性欧美xxxx交| 国产成人亚洲综合青青| 欧美另类极品videosbestfree| 欧美激情在线有限公司| 欧美精品成人91久久久久久久| 在线视频欧美日韩| 日本韩国欧美精品大片卡二| 2018日韩中文字幕| 国产精品久久久久久久久久99| 国产成人精品在线观看| 91精品综合久久久久久五月天| 最近中文字幕2019免费| 日韩福利伦理影院免费| 伊人久久大香线蕉av一区二区| 欧美一区二区三区精品电影| 国产精品视频永久免费播放| 精品久久久久久国产91| 中文字幕日韩精品在线观看| 日韩av电影免费观看高清| 久久久久久网址| 久久亚洲私人国产精品va| 欧美限制级电影在线观看| 国产精品永久免费| 国产成人精品视频在线观看|