欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

c# 斷點續(xù)傳的實現(xiàn)

 更新時間:2020年12月02日 11:15:23   作者:sparkdev  
這篇文章主要介紹了c# 斷點續(xù)傳的實現(xiàn),幫助大家更好的理解和使用c#,感興趣的朋友可以了解下

作者:sparkdev
出處:http://www.cnblogs.com/sparkdev/

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

工作原理

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

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

Range: bytes=500-999

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

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

1.    是不是所有的 web 服務器都支持 Range 頭?
2.    多次請求之間可能會間隔很長的時間,服務器上的文件發(fā)生了變化怎么辦?
3.    如何保存下載的部分數(shù)據(jù)和相關信息?
4.    當我們通過字節(jié)操作把一個文件拼成原始大小后,如何驗證它和源文件一模一樣?

下面我們就帶著這些問題去探究斷點續(xù)傳的一些細節(jié)。

檢查服務器端對斷點續(xù)傳的支持

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

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

當我們下載了一個文件的一部分之后,可能馬上就會接著下載,也可能會過一段時間再下載,也可能永遠不會再接著下載了…
這里的問題是,當下次要接著下載時,如何確定服務器上的文件還是當初下載了一半的那個文件。如果服務器上的文件已經更新了,那無論如何都需要重新從頭開始下載。只有在服務器上的文件沒有發(fā)生變化的情況下,斷點續(xù)傳才有意義。
對于這個問題,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 就是一個標識當前請求內容的字符串,當請求的資源發(fā)生變化后,對應的 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沒有變化,可以斷點續(xù)傳
    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服務器的實現(xiàn)是不是嚴格遵循了 HTTP 協(xié)議!

保存中間結果

這里主要就是用 C# 進行文件操作。大體思路是如果有未下載完的文件,就把新下載的字節(jié)添加到文件的末尾,不再啰嗦,有興趣的同學請直接看 demo 代碼。

驗證文件

在斷點續(xù)傳的過程中,我們以 byte 為單位下載、合并文件,如果整個過程中稍有沒有處理好的異常,可能最后得到的文件就和源文件不太一樣。因此最好是能夠對下載好的文件進行一次校驗??蛇@也是最難、最不容易實現(xiàn)的。因為它需要服務器端的支持,比如服務器端在提供一個可下載文件的同時提供該文件的 MD5 hash。當然,如果服務器端也是我們自己創(chuàng)建的,我們就可以去實現(xiàn)它。但我們又怎么能夠要求現(xiàn)存的 web 服務器都提供這樣的功能呢!

demo

以上就是c# 斷點續(xù)傳的實現(xiàn)的詳細內容,更多關于c# 斷點續(xù)傳的資料請關注腳本之家其它相關文章!

相關文章

  • Unity色子的投擲和點數(shù)的獲得詳析

    Unity色子的投擲和點數(shù)的獲得詳析

    這篇文章主要給大家介紹了關于Unity色子的投擲和點數(shù)的獲得的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2018-10-10
  • C#判斷本地文件是否處于打開狀態(tài)的方法

    C#判斷本地文件是否處于打開狀態(tài)的方法

    這篇文章主要介紹了C#判斷本地文件是否處于打開狀態(tài)的方法,涉及C#操作文件的技巧,非常具有實用價值,需要的朋友可以參考下
    2015-05-05
  • C#正則表達式與HashTable詳解

    C#正則表達式與HashTable詳解

    這篇文章主要介紹了C#正則表達式與HashTable詳解,文章圍繞主題展開詳細的內容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-07-07
  • C#調用Oracle存儲過程的方法

    C#調用Oracle存儲過程的方法

    這篇文章主要介紹了C#調用Oracle存儲過程的方法,包含數(shù)據(jù)庫及C#對應的調用代碼,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-01-01
  • C#利用VS中插件打包并發(fā)布winfrom程序

    C#利用VS中插件打包并發(fā)布winfrom程序

    這篇文章主要為大家詳細介紹了C#利用VS中插件打包并發(fā)布winfrom程序,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-08-08
  • C#短時間內產生大量不重復的隨機數(shù)

    C#短時間內產生大量不重復的隨機數(shù)

    在C#編程中,經常會碰到產生隨機數(shù)的情況,并且是在短時間內產生一組隨機數(shù)。如果這組隨機數(shù)中有大量重復的,則達不到我們的要求
    2013-02-02
  • C#集合之鏈表的用法

    C#集合之鏈表的用法

    這篇文章介紹了C#集合之鏈表的用法,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-04-04
  • C#與C++枚舉的區(qū)別對比和使用案例

    C#與C++枚舉的區(qū)別對比和使用案例

    本文詳細講解了C#與C++枚舉的區(qū)別對比和使用案例,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-04-04
  • C#使用代碼實現(xiàn)春晚撲克牌魔術

    C#使用代碼實現(xiàn)春晚撲克牌魔術

    這篇文章主要為大家詳細介紹了C#如何使用代碼實現(xiàn)龍年春晚撲克牌魔術(守歲共此時),文中的示例代碼講解詳細,感興趣的小伙伴可以了解一下
    2024-02-02
  • C#實現(xiàn)上位機與歐姆龍PLC通訊(FINS)

    C#實現(xiàn)上位機與歐姆龍PLC通訊(FINS)

    這篇文章主要介紹了C#實現(xiàn)上位機與歐姆龍PLC通訊(FINS)方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-05-05

最新評論