当前位置: 首页 > news >正文

桂市做网站的朋友东方城乡与住房建设部网站

桂市做网站的朋友,东方城乡与住房建设部网站,雄县做网站的,深圳 电子商务网站开发技术群里的朋友遇到了这个问题#xff0c;起初的原因是他对文件增加了一个属性配置 fileResult.EnableRangeProcessing true;这个属性我从未遇到过#xff0c;然后#xff0c;去F1查看这个属性的描述信息也依然少的可怜#xff0c;只有简单的描述为(获取或设置为 启用范围…技术群里的朋友遇到了这个问题起初的原因是他对文件增加了一个属性配置 fileResult.EnableRangeProcessing true;这个属性我从未遇到过然后去F1查看这个属性的描述信息也依然少的可怜只有简单的描述为(获取或设置为 启用范围处理 FileResult的值)。 范围处理很容易理解可能就是实现分片下载的关键但是是不是就很简单配置就可以了呢我对此十分感兴趣就开始查询它的实际信息。 EnableRangeProcessing 属性的含义 经查看Asp.net Core 源码可以看到它实际上只是配置了一个头信息。 具体的方法内部只是一个赋值 赋值的是什么呢其实就是一个HTTP 头标记 所以实际上它只做了一件事情那就是把请求的头变成以下的样子。 是的它只是做了这一件事情那就是把请求头 Accept-Ranges 的值设置为了 bytes 。 HTTP 协议头之 Accept-Ranges 经查寻此头就是表示着 (Accept-Ranges HTTP 响应标头是服务器使用的一个标记用于向客户端宣传其对文件下载的部分请求的支持。此字段的值表示可用于定义范围的单位。 ) 当存在 Accept-Ranges 标头时浏览器可能会尝试恢复中断的下载而不是尝试重新启动下载。 所以设置它就相当于设置了Asp.net Core 支持分片下载。 Asp.net Core 分片下载实际案例 主要分为服务端和客户端服务端设置允许分片下载客户端则需要按照分片进行多线程下载我这里实际通过并行下载实现。 最后的验证能运行它或者打开它即可(比如zip格式等)。 服务端代码 服务端异常的简单新建一个Asp.net Core 项目即可其他都默认。 我们要做的事情只是在 HomeController 里增加以下代码 private FileExtensionContentTypeProvider provider new FileExtensionContentTypeProvider(); public IActionResult Down() {var file H:\百度网盘\ubuntu.zip;provider.TryGetContentType(file, out var contentType);var result PhysicalFile(file, contentType);result.EnableRangeProcessing true;result.FileDownloadName Path.GetFileName(file);return result; }里面有几个点 设置文件的类型可以用 FileExtensionContentTypeProvider 这个类来的不用自己写(特殊类型它不支持)设置EnableRangeProcessing 为 true 才能实现分片下载设置FileDownloadName为具体的下载文件名才可以在客户端知道你下载的文件名的名字很重要。 客户端代码 客户端稍微复杂一些得获取文件的大小和名字然后进行多线程下载我这边会进行一个简单的模拟。 直接下载文件的逻辑 public static async Task DownUrl(string url) {var result await client.SendAsync(new HttpRequestMessage(HttpMethod.Get, url), HttpCompletionOption.ResponseHeadersRead);if (result.IsSuccessStatusCode){var filename temp.zip;using (var contentStream await result.Content.ReadAsStreamAsync()){using (var file File.OpenWrite(filename)){await contentStream.CopyToAsync(file);}}} }当然如果不想分片下载可以直接下载即可。 获取文件大小以及名字 public static async Task(long? length, string filename) GetFileLengthandName(string url) {var result await client.SendAsync(new HttpRequestMessage(HttpMethod.Get, url), HttpCompletionOption.ResponseHeadersRead);if (result.IsSuccessStatusCode){return (result.Content.Headers.ContentLength, result.Content.Headers.ContentDisposition.FileName);}return (null, null); }主要就是通过httpclient 自带的头信息直接获取即可。挺简单的。 分片下载核心 首先是对获取到的文件大小进行一个范围的分割 public struct BytesRange {public long Start { get; set; }public long End { get; set; }public long Length { get { return End - Start 1; } }public override string ToString(){return ${Start} {End} : {Length};}public static ListBytesRange GetRanges(long length, long BufferSize 1 * 1024 * 1024){ListBytesRange list new ListBytesRange();long count length / BufferSize;long Lost length - BufferSize * count;if (Lost 0){list.Add(new BytesRange() { Start count * BufferSize, End count * BufferSize Lost - 1 });}if (count 0){for (long i 0; i count; i){list.Add(new BytesRange() { Start i * BufferSize, End (i 1) * BufferSize - 1 });}}else{list.Add(new BytesRange() { Start 0, End Lost - 1 });}list.OrderByDescending(t t.Start);return list;} }这样就可以获取具体的分片信息具体每片的大小。 public static async Taskbyte[] GetBytesAsync(string url, BytesRange range) {var request new HttpRequestMessage(HttpMethod.Get, url);request.Headers.Add(Range, $bytes{range.Start}-{range.End});using (HttpResponseMessage response await client.SendAsync(request)){using (Stream stream await response.Content.ReadAsStreamAsync()){if (range.Length ! stream.Length){throw new Exception(数据不匹配!);}byte[] bytes new byte[stream.Length];stream.Read(bytes, 0, bytes.Length);return bytes;}} }GetBytesAsync 就是按照指定的大小分为进行请求并返回所需的文件大小。 实际代码 static HttpClient client new HttpClient(); static object lockObj new object(); static async Task Main(string[] args) {var url http://localhost:5034/home/down;Stopwatch stopwatch Stopwatch.StartNew();await DownUrl(url);stopwatch.Stop();Console.WriteLine($单线程 直接下载耗时:{stopwatch.Elapsed.TotalSeconds});stopwatch.Restart();(long? length, string filename) await GetFileLengthandName(url);if (length.HasValue){var number 10;//获取分片大小默认1M 缓存区太小又太慢 设置成5M。var list BytesRange.GetRanges(length.Value, 5 * 1024 * 1024);Console.WriteLine($分片数:{list.Count} 每片大小:5MB 并发数:{number});var path Path.Combine(AppContext.BaseDirectory, filename);using (var write File.OpenWrite(path)){write.SetLength(length.Value);await write.FlushAsync();// 并行下载每秒默认10并发Parallel.ForEach(list, new ParallelOptions() { MaxDegreeOfParallelism number }, range {//Console.WriteLine(${DateTime.Now.ToString(yyyy-MM-dd HH:mm:ss.fff)} {range});var bytes GetBytesAsync(url, range).Result;lock (lockObj){write.Seek(range.Start, SeekOrigin.Begin);write.Write(bytes);}});}Console.WriteLine(下载完毕请验证!);}else{Console.WriteLine(没有获取到下载文件的信息!);}stopwatch.Stop();Console.WriteLine($并发下载 耗时:{stopwatch.Elapsed.TotalSeconds}秒);Console.ReadLine(); }验证结果 先运行服务端 再运行下载客户端 看到结果后有点差异 从结果上来看直接下载是最快的应该是少了分片的开销而且服务都是在本机上各种IO的限制基本上只有文件IO带宽IO影响最小。 总结 虽然直接下载是最快的但是如果网络中断的话基本得重新下载所以它的风险反而是最高的而分片下载虽然有了分片的开销的但是可以从断点处继续下载风险反而最低各有优势。 代码地址 https://github.com/kesshei/WebDown.git https://gitee.com/kesshei/WebDown.git 参考资料地址 《enableRangeProcessing 的代码地址》 https://github.com/dotnet/aspnetcore/blob/53db4d97d7c77d13e20e58a98f104e88d6af6040/src/Shared/ResultsHelpers/FileResultHelper.cs#L141 《Accept-Ranges 》 https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Accept-Ranges阅 一键三连呦感谢大佬的支持您的支持就是我的动力!
http://www.hkea.cn/news/14499255/

相关文章:

  • 免费空间访客网站网站设计公司西安
  • 余姚外贸网站建设网站首页改版费用
  • 网站规划的步骤企业网站目的
  • 做的网站访问速度慢广告设计与制作专业就业方向
  • 岳阳网站岳阳建站常用网站推荐
  • 上海站优云网络科技有限公司完成网站的建设工作内容
  • 有个印度做网站的天天找我男生做网站编辑
  • 名城建设有限公司网站中国科技
  • 网站建设编辑教程浅谈一下网络营销的几个误区
  • 个人网站我的大学我做主页面网站与备案信息不符
  • 银行虚拟网站制作有人有片资源吗免费高清
  • 建设企业网站作用小米路由器3 做网站
  • 推广网站企业手机网站开发c 教程
  • iis7添加网站网站目录优化
  • 天津有哪些好的做网站公司网站做视频怎么赚钱的
  • 企业网站推广建议如何在阿里云上做网站备案
  • 免费织梦网站模板创网络用语是什么意思
  • 江门网站关键词推广外链代发公司
  • 北京常用网站wordpress 模板 破解版
  • 有关做粪污处理设备的企业网站网站开发的理解
  • 设计iphone手机网站淘宝网站品牌设计
  • 简历网站免费动画制作专业学校排名
  • 蓝杉网站建设公司建设网站资质查询
  • 4435建站wordpress整合ck
  • 个人网站备案网站名称重庆网站设计中心
  • 做的做的比较好的网站惠州公司网站建设价格
  • 律所网站建设数字展厅网站建设
  • 泰安市景区建设网站天猫网站建设的目的
  • 怎么换自己的网站服务器网站建设及网站推广
  • 宁波网站建设报价多少兰州网络推广优化服务