C#使用HttpClient对大文件进行断点上传和下载

 更新时间:2024年06月25日 09:25:38   作者:猫霸12354  
这篇文章主要介绍了C#如何使用HttpClient对大文件进行断点上传和下载,文章通过代码示例讲解的非常详细,具有一定的参考价值,需要的朋友可以参考下

什么是Http的断点上传和下载

断点上传:在向服务商上传大文件的时候,将一个大的文件拆分成多个小的文件,每个文件通过单独的Http请求上传给服务器。

断点下载:在向服务器请求下载一个大的资源文件的时候,不是一次Http请求返回所有的资源文件内容。而是先通过Head请求,拿到资源文件的大小(单位:字节)。然后每次请求只请求一部分字节的数据,将请求到的数据在本地进行拼接。

断点上传和下载的优点

1、避免网络中断时,重传所有资源文件内容。

2、提高服务器并发,防止单个客户端长时间和服务器保持连接。

3、可以实时显示上传和下载的进度。

断点上传和下载的缺点

1、占用更多的网络带宽,因为每次Http请求都会附带各种额外的信息。

2、上传和下载的时间会变得长一点,因为是通过多次请求来完成断点上传和下载。

实现基本原理

依赖Http协议的几个基本的协议头来完成断点上传和下载。

1、Content-Range:这是一个响应头,表示请求的资源文件大小,我们可以通过Head请求拿到的资源文件的字节数,就是读取的这个字段。

2、Range :这是一个请求头,表示客户端要请求的数组的范围。如如:"0-1000"、"1001-2000"、"2001-3000"等,服务器接收到这个请求头之后,只给我们返回对应范围内的资源字节数组,不会把所有的字节数都返回给我们。

一般请求下,这两个请求头就可以实现简单的断点上传和下载。本篇文章我们使用一个WPF项目演示断点下载。

string url = "http://file.cshelloworld.com/images/1771477326069108736.jpg";
long totalSize = 0;//文件总大小
long downLoadingSize = 0;//当前已经下载了多少

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的进度
            downLoadingSize += bytes.Length;
            int process = (int)((downLoadingSize / (decimal)totalSize) * 100);
            this.Dispatcher.Invoke(() =>
            {
                cont.Text = process + "%";
                this.processBar.Value = process;
            });
        }
        fileStream.Close();
    });
}

在以上代码中,首先是Head请求获取资源文件大小。

我们主要通过以下代码实现,通过设置HttpMethod.Head构建一个HttpRequestMessage的请求对象

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

其次是断点下载过程中,Range请求头如何设置:

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

每次请求到字节数组之后,我们将字节数组写入到本地的文件流中,如果网络断开,下次请求的时候,读取本地文件大小,假设本地未见大小为1000,那么我们请求的时候Range就从1001开始,这样服务器就给我们返回的是1001之后的字节数组了。

当然在这个过程中,我们还要考虑一个问题,如果服务器的资源文件发生了修改会怎么样。如果我们继续下载的话 ,就会出现问题。因为客户端下载的文件都不是同一个文件。这种情况下,我们可以使用Http的请求头Last-Modified来判断文件是否修改,这个请求头表示文件的最近一次修改时间。当我们第一次请求数据的时候可以把这个请求头的时间记录下来,后续请求如果服务器资源文件发生变化,我们就将本地文件全部删除,然后重新发起请求。

以上就是C#使用HttpClient对大文件进行断点上传和下载的详细内容,更多关于C# HttpClient文件上传和下载的资料请关注脚本之家其它相关文章!

相关文章

  • C# SynchronizationContext以及Send和Post使用解读

    C# SynchronizationContext以及Send和Post使用解读

    这篇文章主要介绍了C# SynchronizationContext以及Send和Post使用解读,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-05-05
  • WCF实现进程间管道通信Demo分享

    WCF实现进程间管道通信Demo分享

    下面小编就为大家分享一篇WCF实现进程间管道通信Demo,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2017-12-12
  • C#实现从网络同步标准北京时间的方法

    C#实现从网络同步标准北京时间的方法

    这篇文章主要介绍了C#实现从网络同步标准北京时间的方法,涉及C#操作时间的技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-03-03
  • C# Winform使用扩展方法实现自定义富文本框(RichTextBox)字体颜色

    C# Winform使用扩展方法实现自定义富文本框(RichTextBox)字体颜色

    这篇文章主要介绍了C# Winform使用扩展方法实现自定义富文本框(RichTextBox)字体颜色,通过.NET的静态扩展方法来改变RichTextBox字体颜色,需要的朋友可以参考下
    2015-06-06
  • C#中dynamic关键字的正确用法(推荐)

    C#中dynamic关键字的正确用法(推荐)

    dynamic的出现让C#具有了弱语言类型的特性。dynamic是FrameWork4.0的新特性。这篇文章主要介绍了C#中dynamic关键字的正确用法(推荐)的相关资料,需要的朋友可以参考下
    2016-11-11
  • 详解c# 委托链

    详解c# 委托链

    这篇文章主要介绍了c# 委托链的相关资料,文中讲解非常细致,代码帮助大家更好的理解和学习,感兴趣的朋友可以了解下
    2020-07-07
  • C#判断一个图像是否是透明的GIF图的方法

    C#判断一个图像是否是透明的GIF图的方法

    这篇文章主要介绍了C#判断一个图像是否是透明的GIF图的方法,涉及C#针对gif图片属性的相关操作技巧,需要的朋友可以参考下
    2015-06-06
  • C# Entity Framework中的IQueryable和IQueryProvider详解

    C# Entity Framework中的IQueryable和IQueryProvider详解

    这篇文章主要介绍了C# Entity Framework中的IQueryable和IQueryProvider详解,本文使用实例分析这两个接口的内部实现,需要的朋友可以参考下
    2015-01-01
  • 采用C#代码动态设置文件权限

    采用C#代码动态设置文件权限

    在开发中,我们经常会使用IO操作,例如创建,删除文件等操作。在项目中这样的需求也较多,我们也会经常对这些操作进行编码,但是对文件的权限进行设置,这样的操作可能会手动操作,本文介绍一种采用代码动态对文件设置权限的操作。
    2016-12-12
  • C#实现批量下载图片到本地示例代码

    C#实现批量下载图片到本地示例代码

    这篇文章主要给大家介绍了关于C#如何实现批量下载图片到本地的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用c#具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-11-11

最新评论