前言

上一篇net core WebApi——文件分片上传与跨域请求处理介绍完文件的上传操作,本来是打算紧接着写文件下载,中间让形形色色的事给耽误的,今天还是抽个空整理完文件这块儿,然后就可以鼓捣别的东西了。

开始

这里我们仍然使用基础工程,需要下载的朋友请移步net core Webapi 总目录,代码都是与博客的进度基本同步的。

上传的时候我们介绍过分片的思路,而下载也一样,只是客户端与服务端角色转换下就好了。

后端

  1. 接收前端下载请求,校验请求信息,返回文件基本信息
  2. 根据前端请求文件片段进行下载流处理。

前端

  1. 向后端发起下载请求,获取文件总片段数
  2. 根据片段数循环请求文件片段流进行下载(可单独请求某一片段文件数据)

文件下载相对于上传来说稍微简洁点儿,如果不考虑服务器压力也可以一个a标签解决下载问题,分片的意义就在于每次与服务端的交互减少流量,有些时候我们推荐拿空间换时间,但对于大流量来说还是慢慢来比较好,单次访问量如果大再加上多并发怕是服务器会受不了,所以有了一片片分步来循环访问这个方法。

也是直接来看代码吧,我们在FileController创建几个接口方法RequestDownloadFileFileDownload

        /// <summary>
/// 请求下载文件
/// </summary>
/// <param name="fileInfo">文件参数信息[name]</param>
/// <returns></returns>
[HttpPost, Route("RequestDownload")]
public MessageEntity RequestDownloadFile([FromBody]Dictionary<string, object> fileInfo)
{ } /// <summary>
/// 分段下载文件
/// </summary>
/// <param name="fileInfo">请求参数信息[index,name]</param>
/// <returns></returns>
[HttpPost, Route("Download")]
public async Task<IActionResult> FileDownload([FromBody]Dictionary<string, object> fileInfo)
{ }

RequestDownloadFile

这里说明下,与服务端的操作都要尽可能多的确认身份信息(当然后续会有说这块儿),文件的相关操作也一样需要并且还要严格点儿,我这里就是为了做示例演示所以只传文件信息即可。

        public MessageEntity RequestDownloadFile([FromBody]Dictionary<string, object> fileInfo)
{
MessageEntity message = new MessageEntity();
string fileName = string.Empty;
string fileExt = string.Empty;
if (fileInfo.ContainsKey("name"))
{
fileName = fileInfo["name"].ToString();
}
if (fileInfo.ContainsKey("ext"))
{
fileExt = fileInfo["ext"].ToString();
}
if (string.IsNullOrEmpty(fileName))
{
message.Code = -1;
message.Msg = "文件名不能为空";
return message;
}
//获取对应目录下文件,如果有,获取文件开始准备分段下载
string filePath = $".{AprilConfig.FilePath}{DateTime.Now.ToString("yyyy-MM-dd")}/{fileName}";
filePath = $"{filePath}{fileExt}";
FileStream fs = null;
try
{
if (!System.IO.File.Exists(filePath))
{
//文件为空
message.Code = -1;
message.Msg = "文件尚未处理完";
return message;
}
fs = new FileStream(filePath, FileMode.Open);
if (fs.Length <= 0)
{
//文件为空
message.Code = -1;
message.Msg = "文件尚未处理完";
return message;
}
int shardSize = 1 * 1024 * 1024;//一次1M
RequestFileUploadEntity request = new RequestFileUploadEntity();
request.fileext = fileExt;
request.size = fs.Length;
request.count = (int)(fs.Length / shardSize);
if ((fs.Length % shardSize) > 0)
{
request.count += 1;
}
request.filedata = GetCryptoString(fs); message.Data = request;
}
catch (Exception ex)
{
LogUtil.Debug($"读取文件信息失败:{filePath},错误信息:{ex.Message}");
}
finally
{
if (fs != null)
{
fs.Close();
}
} return message;
}

FileDownload

        public async Task<IActionResult> FileDownload([FromBody]Dictionary<string, object> fileInfo)
{
//开始根据片段来下载
int index = 0;
if (fileInfo.ContainsKey("index"))
{
int.TryParse(fileInfo["index"].ToString(), out index);
}
else
{
return Ok(new { code = -1, msg = "缺少参数" });
}
string fileName = string.Empty;
string fileExt = string.Empty;
if (fileInfo.ContainsKey("name"))
{
fileName = fileInfo["name"].ToString();
}
if (fileInfo.ContainsKey("ext"))
{
fileExt = fileInfo["ext"].ToString();
}
if (string.IsNullOrEmpty(fileName))
{
return Ok(new { code = -1, msg = "文件名不能为空" });
}
//获取对应目录下文件,如果有,获取文件开始准备分段下载
string filePath = $".{AprilConfig.FilePath}{DateTime.Now.ToString("yyyy-MM-dd")}/{fileName}";
filePath = $"{filePath}{fileExt}";
if (!System.IO.File.Exists(filePath))
{
return Ok(new { code = -1, msg = "文件尚未处理" });
}
using (var fs = new FileStream(filePath, FileMode.Open))
{
if (fs.Length <= 0)
{
return Ok(new { code = -1, msg = "文件尚未处理" });
}
int shardSize = 1 * 1024 * 1024;//一次1M
int count = (int)(fs.Length / shardSize);
if ((fs.Length % shardSize) > 0)
{
count += 1;
}
if (index > count - 1)
{
return Ok(new { code = -1, msg = "无效的下标" });
}
fs.Seek(index * shardSize, SeekOrigin.Begin);
if (index == count - 1)
{
//最后一片 = 总长 - (每次片段大小 * 已下载片段个数)
shardSize = (int)(fs.Length - (shardSize * index));
}
byte[] datas = new byte[shardSize];
await fs.ReadAsync(datas, 0, datas.Length);
//fs.Close();
return File(datas, "application/x-gzip");
}
}

看过上传的朋友都清楚上传是三步,请求上传=>开始上传=>合并,而下载只需要两步,因为合并与否其实不那么重要了,反正文件流都给客户端了,那边自己判断需要重新下载还是下载部分片段都是他们自己的事了(服务端只管卖,东西有问题自己解决,多理想的状态)。

测试

搞完之后重新生成,运行之后我们来测试下效果,测试之前不要忘了接口白名单(做过登录相关的验证操作的忽略这点)。

这里提示error是因为解析错误,实际请求下载测试是正常的,如果有异常问题可以与我联系。

小结

文件相关的上传下载以及常规信息的操作可以告一段落,至于下一步鼓捣点儿啥也还没想好,本来还在看着linux相关的操作做发布部署的铺垫,看最近总体的进度吧,总之,学如逆水行舟,如果不想溺水,就握好你的浆(当然有些人不用浆那就算了,告辞)。

net core WebApi——文件分片下载的更多相关文章

  1. net core WebApi——文件分片上传与跨域请求处理

    目录 前言 开始 测试 跨域 小结 @ 前言 在之前整理完一套简单的后台基础工程后,因为业务需要鼓捣了文件上传跟下载,整理完后就迫不及待的想分享出来,希望有用到文件相关操作的朋友可以得到些帮助. 开始 ...

  2. 如何在启用JWT Token授权的.NET Core WebApi项目中下载文件

    背景 前几天,做项目的时候遇到一个文件下载的问题.当前系统是一个前后端分离的项目,前端是一个AngularJs项目, 后端是一个.NET Core WebApi项目.后端的Api项目使用了Jwt To ...

  3. .net core webapi 文件上传在 Swagger 文档中的有好提示处理

    前提: 需要nuget   Swashbuckle.AspNetCore 我暂时用的是  4.01 最新版本: 描述:解决 .net core webapi 上传文件使用的是 IFormFile,在S ...

  4. asp.net core webapi文件上传

    最近开发一个新项目,使用了asp.net core 2.0,采用webapi开发后台,postgresql为数据库.最先来的问题就是上传文件的问题. POST文件的一些坑 使用默认模板创建webapi ...

  5. .NET Core Web 文件分片上传,带进度条实用插件

    话不多说,上源码连接: 链接:https://pan.baidu.com/s/1_u15zqAjhH0aVpeoyVMfUA 提取码:z209

  6. net core WebApi——使用NPOI导入导出操作

    目录 前言 NPOI 测试 小结 @ 前言 时间过得好快,在之前升级到3.0之后,就感觉好久没再动过啥东西了,之前有问到Swagger的中文汉化,虽说我觉得这种操作的意义不是太大,也是多少鼓捣了下,其 ...

  7. ASP.NET CORE WEBAPI文件下载

    ASP.NET CORE WEBAPI文件下载 最近要使用ASP.NET CORE WEBAPI用来下载文件,使用的.NET CORE 3.1.考虑如下场景: 文件是程序生成的. 文件应该能兼容各种格 ...

  8. 用Electron开发企业网盘(二)--分片下载

    书接上文,背景见:https://www.cnblogs.com/shawnyung/p/10060119.html HTTP请求头  Range 请求资源的部分内容(不包括响应头的大小),单位是by ...

  9. 上传数据、下载模板文件解决方案(前端:antd;后端:.Net Core WebAPI)

    一.Excel 模板下载 通过静态文件下载. 将模板文件放在根目录的 public 文件夹下备用. 下载事件方法如下:(通过临时生成一个 a 标签,触发后再移除) downLoadExcelModel ...

随机推荐

  1. 个人永久性免费-Excel催化剂功能第44波-可见区域复制粘贴不覆盖隐藏内容

    Excel的复制粘贴操作,每天都在进行,若其中稍能提升一点效率,长久来说,实在是很可观的效率提升. Excel自带的复制粘贴功能,若复制的数据源或粘贴的目标位置中有隐藏的行列内容,简单一个复制粘贴充满 ...

  2. Python开发:NumPy学习(一)ndarray数组

    一.数据维度 一个数据表达一个含义,一组数据表达一个或多个含义. 数据维度概念:一组数据的组织形式,其中有一维数据.二维数据.多维数据.高维数据. 1.  一维数据 一维数据由对等关系的有序或无序数据 ...

  3. Servlet和JSP知识总结

    1.Servlet接口有哪些方法及Servlet生命周期 Servlet接口定义了5个方法,前三个方法与Servlet生命周期有关: void init() void service() void d ...

  4. activiti工作流委托功能的设计和实现

    最近公司开发一个项目,客户提出了一个需求,用户在出差的时候,可以将自己的工作进行委托.可以指定委托时间.委托工作内容.指定委托人等等内容. 然后我就上网查询资料,发现activiti工作流本身并不支持 ...

  5. Centos7安装mysql8教程

    网上的教程很多,我也参考了很多,以下是我实践的步骤,真实有效. 1.配置Mysql 8.0安装源: sudo rpm -Uvh https://dev.mysql.com/get/mysql80-co ...

  6. T-SQL 镜像测试

    --====================================================== ----镜像计划建立 2016-05-10 17:05:16.463 hubiyun ...

  7. ASP.NET Core on K8S深入学习(1)K8S基础知识与集群搭建

    在上一个小系列文章<ASP.NET Core on K8S学习初探>中,通过在Windows上通过Docker for Windows搭建了一个单节点的K8S环境,并初步尝试将ASP.NE ...

  8. 箭头函数=>

    箭头函数特点一:没有自己的this对象,其this对象为所在环境 特点二 :没有arguments参数 可以用...rest代替特点三:不能使用构造函数,不可使用new命令,否则会报错 //函数的扩展 ...

  9. 华为路由交换综合实验 ---IA阶段

    目录 华为路由交换综合实验 ---IA阶段 实验拓扑 实验需求 华为路由交换综合实验 ---IA阶段 实验拓扑 实验需求 根据拓扑合理规划IP地址以及VLANIf地址(PC1属于运营部,PC2属于市场 ...

  10. Guitar Pro如何更改五线谱的符杆方向

    可能有的小伙伴不知道Guitar Pro是什么软件,我先稍微给大家介绍一下~ Guitar Pro是专为帮助所有吉他爱好者学习.绘谱.创作的多功能软件.它包含所有吉他的现有指法和音色,可以帮助我们了解 ...