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

C#使用HttpClient對大文件進(jìn)行斷點(diǎn)上傳和下載

 更新時(shí)間:2024年06月25日 09:25:38   作者:貓霸12354  
這篇文章主要介紹了C#如何使用HttpClient對大文件進(jìn)行斷點(diǎn)上傳和下載,文章通過代碼示例講解的非常詳細(xì),具有一定的參考價(jià)值,需要的朋友可以參考下

什么是Http的斷點(diǎn)上傳和下載

斷點(diǎn)上傳:在向服務(wù)商上傳大文件的時(shí)候,將一個(gè)大的文件拆分成多個(gè)小的文件,每個(gè)文件通過單獨(dú)的Http請求上傳給服務(wù)器。

斷點(diǎn)下載:在向服務(wù)器請求下載一個(gè)大的資源文件的時(shí)候,不是一次Http請求返回所有的資源文件內(nèi)容。而是先通過Head請求,拿到資源文件的大?。▎挝唬鹤止?jié))。然后每次請求只請求一部分字節(jié)的數(shù)據(jù),將請求到的數(shù)據(jù)在本地進(jìn)行拼接。

斷點(diǎn)上傳和下載的優(yōu)點(diǎn)

1、避免網(wǎng)絡(luò)中斷時(shí),重傳所有資源文件內(nèi)容。

2、提高服務(wù)器并發(fā),防止單個(gè)客戶端長時(shí)間和服務(wù)器保持連接。

3、可以實(shí)時(shí)顯示上傳和下載的進(jìn)度。

斷點(diǎn)上傳和下載的缺點(diǎn)

1、占用更多的網(wǎng)絡(luò)帶寬,因?yàn)槊看蜨ttp請求都會(huì)附帶各種額外的信息。

2、上傳和下載的時(shí)間會(huì)變得長一點(diǎn),因?yàn)槭峭ㄟ^多次請求來完成斷點(diǎn)上傳和下載。

實(shí)現(xiàn)基本原理

依賴Http協(xié)議的幾個(gè)基本的協(xié)議頭來完成斷點(diǎn)上傳和下載。

1、Content-Range:這是一個(gè)響應(yīng)頭,表示請求的資源文件大小,我們可以通過Head請求拿到的資源文件的字節(jié)數(shù),就是讀取的這個(gè)字段。

2、Range :這是一個(gè)請求頭,表示客戶端要請求的數(shù)組的范圍。如如:"0-1000"、"1001-2000"、"2001-3000"等,服務(wù)器接收到這個(gè)請求頭之后,只給我們返回對應(yīng)范圍內(nèi)的資源字節(jié)數(shù)組,不會(huì)把所有的字節(jié)數(shù)都返回給我們。

一般請求下,這兩個(gè)請求頭就可以實(shí)現(xiàn)簡單的斷點(diǎn)上傳和下載。本篇文章我們使用一個(gè)WPF項(xiàng)目演示斷點(diǎn)下載。

string url = "http://file.cshelloworld.com/images/1771477326069108736.jpg";
long totalSize = 0;//文件總大小
long downLoadingSize = 0;//當(dāng)前已經(jīng)下載了多少

private void Button_Click(object sender, RoutedEventArgs e)
{
    Task.Run(async () =>
    {
        //獲取到文件總大小 通過head請求
        using HttpClient client = new HttpClient();
        HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Head, url);
        var response = await client.SendAsync(requestMessage);
        totalSize = response.Content.Headers.ContentLength.Value;
        using FileStream fileStream = new FileStream("d:\a.jpj", FileMode.Create, FileAccess.Write, FileShare.Read);

        //開始分片下載
        while (downLoadingSize < totalSize)
        {
            //組裝range 0,1000 1000,2000 0,9999
            long start = downLoadingSize;
            long end = start + 1000;
            if (end > (totalSize - 1))
            {
                end = totalSize - 1;
            }
            client.DefaultRequestHeaders.Range = new System.Net.Http.Headers.RangeHeaderValue(start, end);
            var res = await client.GetAsync(url);
            byte[] bytes = await res.Content.ReadAsByteArrayAsync();
            await fileStream.WriteAsync(bytes, 0, bytes.Length);
            //更新UI的進(jìn)度
            downLoadingSize += bytes.Length;
            int process = (int)((downLoadingSize / (decimal)totalSize) * 100);
            this.Dispatcher.Invoke(() =>
            {
                cont.Text = process + "%";
                this.processBar.Value = process;
            });
        }
        fileStream.Close();
    });
}

在以上代碼中,首先是Head請求獲取資源文件大小。

我們主要通過以下代碼實(shí)現(xiàn),通過設(shè)置HttpMethod.Head構(gòu)建一個(gè)HttpRequestMessage的請求對象

HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Head, url);

其次是斷點(diǎn)下載過程中,Range請求頭如何設(shè)置:

client.DefaultRequestHeaders.Range = new System.Net.Http.Headers.RangeHeaderValue(start, end);

每次請求到字節(jié)數(shù)組之后,我們將字節(jié)數(shù)組寫入到本地的文件流中,如果網(wǎng)絡(luò)斷開,下次請求的時(shí)候,讀取本地文件大小,假設(shè)本地未見大小為1000,那么我們請求的時(shí)候Range就從1001開始,這樣服務(wù)器就給我們返回的是1001之后的字節(jié)數(shù)組了。

當(dāng)然在這個(gè)過程中,我們還要考慮一個(gè)問題,如果服務(wù)器的資源文件發(fā)生了修改會(huì)怎么樣。如果我們繼續(xù)下載的話 ,就會(huì)出現(xiàn)問題。因?yàn)榭蛻舳讼螺d的文件都不是同一個(gè)文件。這種情況下,我們可以使用Http的請求頭Last-Modified來判斷文件是否修改,這個(gè)請求頭表示文件的最近一次修改時(shí)間。當(dāng)我們第一次請求數(shù)據(jù)的時(shí)候可以把這個(gè)請求頭的時(shí)間記錄下來,后續(xù)請求如果服務(wù)器資源文件發(fā)生變化,我們就將本地文件全部刪除,然后重新發(fā)起請求。

以上就是C#使用HttpClient對大文件進(jìn)行斷點(diǎn)上傳和下載的詳細(xì)內(nèi)容,更多關(guān)于C# HttpClient文件上傳和下載的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • c#獲取數(shù)組中最大數(shù)的值

    c#獲取數(shù)組中最大數(shù)的值

    這篇文章主要介紹了c#獲取數(shù)組中最大數(shù)的值,需要的朋友可以參考下
    2014-02-02
  • C#微信公眾號(hào)開發(fā)之用戶管理

    C#微信公眾號(hào)開發(fā)之用戶管理

    這篇文章介紹了C#微信公眾號(hào)開發(fā)之用戶管理,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-06-06
  • C# 靈活使用類的方法

    C# 靈活使用類的方法

    本文主要介紹了C# 靈活使用類的方法,具有很好的參考價(jià)值,下面跟著小編一起來看下吧
    2017-02-02
  • 關(guān)于nancy中的身份驗(yàn)證

    關(guān)于nancy中的身份驗(yàn)證

    在nancy中,身份驗(yàn)證分為basic ,form ,token,stateless幾種,basic和form這里不說了,本文重點(diǎn)介紹token驗(yàn)證,需要的朋友一起看看吧
    2015-09-09
  • C#讀寫EXCEL單元格的問題實(shí)現(xiàn)

    C#讀寫EXCEL單元格的問題實(shí)現(xiàn)

    這篇文章主要介紹了C#讀寫EXCEL單元格的問題實(shí)現(xiàn),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2019-04-04
  • C#編程實(shí)現(xiàn)帶有Aero效果的窗體示例

    C#編程實(shí)現(xiàn)帶有Aero效果的窗體示例

    這篇文章主要介紹了C#編程實(shí)現(xiàn)帶有Aero效果的窗體,涉及C#調(diào)用動(dòng)態(tài)鏈接庫針對窗體屬性的相關(guān)操作技巧,需要的朋友可以參考下
    2017-07-07
  • 在C#中實(shí)現(xiàn)接口事件的具體示例

    在C#中實(shí)現(xiàn)接口事件的具體示例

    在C#中,接口(interface)是一種定義類必須實(shí)現(xiàn)的方法和屬性的抽象類型,除了方法和屬性,接口還可以包含事件,實(shí)現(xiàn)接口事件可以幫助我們設(shè)計(jì)更加靈活和解耦的系統(tǒng),本文將詳細(xì)探討如何在C#中實(shí)現(xiàn)接口事件,并通過具體示例說明其應(yīng)用,需要的朋友可以參考下
    2024-08-08
  • C#科學(xué)繪圖之使用scottPlot繪制多個(gè)圖像

    C#科學(xué)繪圖之使用scottPlot繪制多個(gè)圖像

    ScottPlot是基于.Net的一款開源免費(fèi)的交互式可視化庫,支持Winform和WPF等UI框架,本文主要為大家詳細(xì)介紹了如何使用scottPlot實(shí)現(xiàn)繪制多個(gè)圖像,需要的可以參考下
    2023-12-12
  • 在C#中捕獲內(nèi)存不足異常

    在C#中捕獲內(nèi)存不足異常

    這篇文章主要介紹了在C#中捕獲內(nèi)存不足異常,下面文章內(nèi)容圍繞如何在C#中捕獲內(nèi)存不足異常的相關(guān)資料展開詳細(xì)內(nèi)容,具有一定的參考價(jià)值,需要的小伙伴可以參考一下,希望對你有所幫助
    2021-12-12
  • C#及WPF獲取本機(jī)所有字體和顏色的方法

    C#及WPF獲取本機(jī)所有字體和顏色的方法

    這篇文章主要介紹了C#及WPF獲取本機(jī)所有字體和顏色的方法,實(shí)例分析了C#及WPF獲取本機(jī)字體及顏色的相關(guān)技巧,非常簡單實(shí)用,需要的朋友可以參考下
    2015-09-09

最新評(píng)論