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

news/2024/9/22 12:33:03

什么是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,9999long 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#弃元表达式的用法
  •  记录一次JSON.NET反序列化带来的内存爆炸问题
  •  C#如何使用HttpClient对大文件进行断点上传和下载
  •  Windows Api如何创建一个快捷方式并且在开始菜单搜索到自己的应用
  •  .NET Core配置文件发生变更的时候,程序如何接受
  •  C#如何将文件压缩成ZIP并且实时显示压缩进度
  •  线性表
  •  顺序栈
  •  链栈
  •  数组实现队列

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/47039.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

【NAS】绿联NAS+alist+lsky+natfrp 实现图床服务

alist 安装与配置值得一提的就是,映射的data是配置相关的,让绿联直接默认路径就行,不需要手动设置 但是文件保存位置的映射的话,为了方便,可以单独映射到一个方便访问的文件夹,(但是要注意下权限问题) 端口,穿透的是(20010:5244)这个端口创建完毕,账号默认admin,密…

基于布谷鸟搜索的多目标优化matlab仿真

1.程序功能描述基于布谷鸟搜索的多目标优化,设置三个目标函数,进行多目标优化,输出三维优化曲面以及收敛曲线。2.测试软件版本以及运行结果展示 MATLAB2022a版本运行3.核心程序X0 = func_obj(X0); %基于非支配排序对它们进行排名 X0 = func_sort(X0,1); %基…

Ocelot错误解决

上图本来好好的,不知道改了哪里,最后时ocelot.json里注释时一个逗号没了,没报错,运行正常,但是控制台有问题(找到这里也找了半天,前面在其他系统一个个排查)。最后把注释的addjson 文件加上,瞬间报错。我草了啊

[GodotDL C# D2]从空格控制转弯到撞墙检测

书接上回:https://www.cnblogs.com/meny233/p/18250399 新增功能: 空格控制转弯 导出变量 撞墙检测 音乐播放 前戏点击查看代码 using Godot; using System;public partial class Line : CharacterBody3D {[Export]public float Speed = 10f;[Export]public bool turn = fals…

设计模式-观察者模式

观察者模式 观察者模式(Observer Pattern),又叫发布-订阅(Publisher/Subscribe)模式,模型-视图模式,源-监听器模式或从属者模式。定义一种一对多的依赖关系,一个主题对象可以同时被多个监听者同时监听,使得每当主题对象状态发生变化时,所有依赖于它的对象都会得到通知…

王鼎杯 RCE命令執行 五字節限制

源碼: <?php error_reporting(0); highlight_file(__FILE__); if(strlen($_GET[cmd])<=5 && !preg_match(/rm/,$_GET[cmd])) {echo shell_exec($_GET[cmd]); } ?>对cmd限制长度五字节起初是想通过变量来绕过五字节 但好像不起作用 于是尝试使用 常规做法通…

C - Tile Distance 2

C - Tile Distance 2 https://atcoder.jp/contests/abc359/tasks/abc359_c思路 在x方向上,让s<t 然后 如果s在tile的左边,移动到右边, 如果t在tile的右边,移动到左边, 计算x 和 y方便的必走的steps, y方向上容易计算(跨的格子就是), x方向有些复杂, s在x方向上,…

一、系统学习微服务遇到的问题集合

1、启动了nacos服务,没有在注册列表 应该是版本问题 Alibaba-nacos版本 nacos-文档 Spring Cloud Alibaba-中文 Spring-Cloud-Alibaba-英文 Spring-Cloud-Gateway 写的很好的一篇文章在Spring initial上面配置 start.aliyun.com 重新下载 < 2、 No Feign Client for loadBa…