后端实现大文件分片上传

项目框架 net6 webapi

放开上传大小限制

放开代码 | 框架层限制

在 Program.cs 文件中添加如下代码
不然会出现下面的限制错误

From表单限制:Failed to read the request form. Multipart body length limit 134217728 exceeded
请求体超长:Request body too large. The max request body size is 30000000 bytes.

builder.Services.Configure<KestrelServerOptions>(x =>{x.AllowSynchronousIO = true; // 配置可以同步请求读取流数据x.Limits.MaxRequestBodySize = int.MaxValue;}).Configure<IISServerOptions>(x =>{x.AllowSynchronousIO = true;x.MaxRequestBodySize = int.MaxValue; // 设置请求体可接收的最大值}).Configure<FormOptions>(x =>{// 设置表单上传文件的大小限制// 如果不配置,默认是128兆x.MultipartBodyLengthLimit = int.MaxValue;});

设置 nginx 或 iis 中的大小限制

IIS 层

找到对应程序的 web.config
添加如下代码配置:

<security><requestFiltering><!-- 1000 MB in bytes --><requestLimits maxAllowedContentLength="1048576000" /></requestFiltering></security>

若缺少 system.webServer 等节点,添加上即可
image.png

nginx 层

在 conf 文件里的 nginx.conf 配置文件 http 中添加节点

client_max_body_size 1000m;

image.png

分片上传代码实现

请求参数 UploadFileInChunksVO 类

/// <summary>
/// 功 能: N/A
/// V0.01 2023/10/24 17:56:36 xliu  初版
/// </summary>
public class UploadFileInChunksVO
{        /// <summary>///  分片后的文件/// </summary>public IFormFile File { get; set; }/// <summary>/// 当前块,从1开始/// </summary>public int ChunkNumber { get; set; }/// <summary>/// 总块数/// </summary>public int TotalChunks { get; set; }
}

添加控制器 Controller

必须添加 [FromForm] 标识,不然 FIle 识别不到

AppSettings 是一个自行实现读取配置文件的方法
RunInterceptException 是自定义的异常类,统一错误捕获处会对这个做 400 的异常处理

public async Task<IActionResult> UploadFile([FromForm] UploadFileInChunksVO chunksVO)
{if (chunksVO.ChunkNumber == 0 || chunksVO.TotalChunks == 0)throw new RunInterceptException("上传的数据块标识能为0");// 创建用于存储上传文件的文件夹// 可以是读取当前服务的地址,我这边项目是集群化的所有存储地址必须是一个地方不然没办法合并var path = AppSettings.app(new string[] { "Startup", "AppData" }); if (path == null || path.IsNullOrEmpty())throw new RunInterceptException("文件存储服务路径为空");var folderPath = Path.Combine(path, "Uploads", "JD_EDI");var tempPath = Path.Combine(folderPath, "Temp");await _fileService.UploadFileInChunksAsync(chunksVO.File, tempPath, chunksVO.ChunkNumber);// 上传最后一块了 进行合并if (chunksVO.ChunkNumber == chunksVO.TotalChunks){// 构造合并后的文件路径var mergedFilePath = Path.Combine(folderPath, chunksVO.File.FileName);await _fileService.MergeFileAsync(mergedFilePath, tempPath, chunksVO.File.FileName, chunksVO.TotalChunks);// 合并后的操作var res = await _ediService.SalesStockAsync(mergedFilePath);return Ok("处理成功数:" + res);}return Ok("接收成功");
}

服务接口定义 IUploadFileService

项目做了接口、服务分离。使用依赖注入的方式
若没这项要求的 可以直接使用后面的方法实现

/// <summary>
/// 功 能: 上传文件服务
/// V0.01 2023/10/24 15:01:01 xliu  初版
/// </summary>
public interface IUploadFileService
{/// <summary>/// 分片上传文件/// </summary>/// <param name="file">正在上传的文件</param>/// <param name="tempFilePath">临时存储分片数据的目录</param>/// <param name="chunkNumber">当前分片块</param>/// <returns>最终文件保存路径</returns>Task<string> UploadFileInChunksAsync(IFormFile file, string tempFilePath , int chunkNumber);/// <summary>/// 用于合并文件块并处理完整文件的方法/// </summary>/// <param name="mergedFilePath">合并后文件的保存地址</param>/// <param name="tempPath">分片文件的保存地址</param>/// <param name="fileName"></param>/// <param name="totalChunks"></param>/// <returns></returns>Task MergeFileAsync(string mergedFilePath, string tempPath, string fileName, int totalChunks);
}

服务接口实现 UploadFileService

/// <summary>
/// 功 能: N/A
/// V0.01 2023/10/24 15:05:09 xliu  初版
/// </summary>
public class UploadFileService : IUploadFileService
{public async Task<string> UploadFileInChunksAsync(IFormFile file, string tempPath, int chunkNumber){if (!Directory.Exists(tempPath)){Directory.CreateDirectory(tempPath);}// 构造当前块文件的路径var filePath = Path.Combine(tempPath, file.FileName + "_" + chunkNumber);// 将文件块写入磁盘using (var fileStream = new FileStream(filePath, FileMode.Create)){await file.CopyToAsync(fileStream);}return filePath;}public async Task MergeFileAsync(string mergedFilePath, string tempPath, string fileName, int totalChunks){// 创建用于存储合并后文件的流using var mergedFileStream = new FileStream(mergedFilePath, FileMode.Create);// 循环处理每个文件块for (int i = 1; i <= totalChunks; i++){// 构造当前文件块的路径var chunkFilePath = Path.Combine(tempPath, fileName + "_" + i);// 创建用于读取文件块的流using (var chunkFileStream = new FileStream(chunkFilePath, FileMode.Open)){// 将文件块内容复制到合并文件流中await chunkFileStream.CopyToAsync(mergedFileStream);}// 删除已合并的文件块System.IO.File.Delete(chunkFilePath);}}

上传测试

这边只给到 postman 的示例
前端实现 无非就是根据文件大小切分成多个文件 单次上传一部分
每次上传变化 file 和 chuckNumber 即可,当 chunkNumber 和 totalChunks 相等时便上传完成
image.png

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Win10中Pro/E鼠标滚轮不能缩放该怎么办?

Pro/E安装好后&#xff0c;鼠标滚轮不能缩放模型&#xff0c;该怎么办&#xff1f;问题多发生在win8/win10上&#xff0c;新装了PROE&#xff0c;发现滑动鼠标中键不能放大缩小。 彩虹图纸管理软件_图纸管理系统_图纸文档管理软件系统_彩虹EDM【官网】彩虹EDM图纸管理软件系统…

【PyQt】调整子控件的层级以调整绘制的先后顺序

简述 qt中貌似没有直接设置z序的函数&#xff0c;但对应的有其他调整z序的方法&#xff1a; QWidget.raise_()&#xff1a;置顶 QWidget.lower()&#xff1a;置底 QWidget.stackUnder(wid)&#xff1a;置于指定控件之下 其中关键函数是QWidget.stackUnder(wid)&#xff0c;利…

Python---使用turtle模块+for循环绘制五角星---利用turtle(海龟)模块

首先了解涉及的新词汇&#xff0c;编程外国人发明的&#xff0c;所以大部分是和他们语言相关&#xff0c;了解对应意思&#xff0c;可以更好理解掌握。 import 英 /ˈɪmpɔːt/ n. 进口&#xff0c;进口商品&#xff1b;输入&#xff0c;引进&#xff1b;重要性&#xff1b;…

【Unity】3D跑酷游戏

展示 finish_all * 方块跑酷 1.教程链接 翻墙&#xff1a;https://www.youtube.com/watch?v9ZEu_I-ido4&listPLPV2KyIb3jR53Jce9hP7G5xC4O9AgnOuL&index3 2.基础制作 最终成果 2.1 基本场景 1.创建Cube作为跑道 1&#xff09;记得把位置Reset&#xff1b; 2&#…

Linux部署Redis Cluster高可用集群(附带集群节点添加删除以及槽位分配操作详解)

目录 一、前言二、下载安装Redis2.1、选择需要安装的Redis版本2.2、下载并解压Redis2.3、编译安装Redis 三、部署Redis Cluster高可用集群3.1、准备配置文件3.2、启动Redis服务3.3、创建Redis集群3.4、查看集群关系3.5、连接集群Redis进行数据读写以及重定向测试3.6、故障转移和…

使用Scala和Sttp库编写爬虫程序

以下是一个使用Scala和Sttp库编写的视频爬虫程序&#xff0c;该程序使用了proxy来获取IP。请注意&#xff0c;这个示例需要在上找到一个具体的视频链接&#xff0c;然后将其传递给crawlVideo函数。 import scala.util.{Failure, Success} import scala.concurrent.{Future, Ex…

基于计算机视觉的坑洼道路检测和识别-MathorCup A(深度学习版本)

1 2023 年 MathorCup 高校数学建模挑战赛——大数据竞赛 赛道 A&#xff1a;基于计算机视觉的坑洼道路检测和识别 使用深度学习模型&#xff0c;pytorch版本进行图像训练和预测&#xff0c;使用ResNet50模型 2 文件夹预处理 因为给定的是所有图片都在一个文件夹里面&#xf…

安信可小安派AiPi 代码下载

安信可小安派AiPi 代码下载笔记记录 AiPi 代码下载&#xff08;直接使用命令行操作&#xff0c;仅需要Type-C接口线即可&#xff09; 在完成环境搭建&#xff0c;和代码编写前提下&#xff0c;使用Type-C接口线下载代码&#xff0c;当然可以自己使用usb-ttl串口线下载程序&am…

SQL server 代理服务启动和查看

设置重启 使用管理员权限登录到运行 SQL Server 代理服务的计算机。 打开 Windows 服务管理器。可以通过按下 Windows 键 R&#xff0c;然后键入 "services.msc" 并按 Enter 来打开服务管理器。 在服务列表中&#xff0c;找到 "SQL Server Agent" 服务&…

回归算法|长短期记忆网络LSTM及其优化实现

本期文章将介绍LSTM的原理及其优化实现 序列数据有一个特点&#xff0c;即“没有曾经的过去则不存在当前的现状”&#xff0c;这类数据以时间为纽带&#xff0c;将无数个历史事件串联&#xff0c;构成了当前状态&#xff0c;这种时间构筑起来的事件前后依赖关系称其为时间依赖&…

解决:谷歌浏览器访问http时,自动转https访问的问题

问题背景&#xff1a;某个系统网站&#xff0c;之前一直用https域名访问&#xff0c;现在改成http域名后&#xff0c;用http访问&#xff0c;谷歌浏览器会自动跳转到https。 解决方法&#xff1a; 在浏览器中输入网址&#xff1a;chrome://net-internals/#hsts -》 在“Delete…

解决git action定时任务执行失败的方法

为了测试git action定时任务是否有效&#xff0c;你可能选择一个最近的时间测试&#xff0c; 但是发现怎么也触发不了&#xff0c;是不是觉得很苦恼。但是同样的时间&#xff0c;在第二天的定时任务又能成功运行。 这是什么原因&#xff1f; 原因就在上图&#xff0c;git act…

多测师肖sir_高级金牌讲师__接口测试之tonken (5.6)

接口测试之tonken 网站&#xff1a;http://shop.duoceshi.com/login?redirect2Fdashboard 第一个接口&#xff1a;uiid接口 uiid接口url&#xff1a;http://manage.duoceshi.com/auth/code test中语句&#xff1a; var jsonData JSON.parse(responseBody); postman.setEnvi…

NewStarCTF2023week4-溯源

题目描述是冰蝎进行WebShell连接的流量包&#xff0c;我们需要找到攻击者获取到的服务器用户名和服务器内网IP地址。 先介绍一下常见webshell工具的流量特征&#xff1a; 1、中国菜刀 请求体中存在eval、base64等特征字符&#xff1b; 连接过程中使用base64编码对发送的指令…

深入探究深度学习、神经网络与卷积神经网络以及它们在多个领域中的应用

目录 1、什么是深度学习&#xff1f; 2、深度学习的思想 3、深度学习与神经网络 4、深度学习训练过程 4.1、先使用自下上升非监督学习&#xff08;就是从底层开始&#xff0c;一层一层的往顶层训练&#xff09; 4.2、后自顶向下的监督学习&#xff08;就是通过带标签的数…

jenkins自动化操作步骤(gitblit)

1、登陆地址&#xff1a; http://xxxxxxxxx.org:xxxx/ admin/xxxx 2、创建任务 选择构建一个maven项目 3、配置 最多只保留一天一个任务 选择git仓库和账号密码 选择代码对应分支 build项&#xff1a; 1&#xff09;使用父项目的pom文件&#xff1a;k56-boot/pom.xml 2&…

【Qt之QtConcurrent】描述及使用

描述 QtConcurrent是一个Qt库中的模块&#xff0c;用于实现多线程并发编程。它提供了一些高级API&#xff0c;使得在多核处理器上并行执行代码变得更加容易。 示例&#xff1a; 使用的话&#xff0c; 需要在pro文件中添加&#xff1a;QT concurrent模块。 #include <QC…

Leetcode刷题详解——第 N 个泰波那契数

1. 题目链接&#xff1a;1137. 第 N 个泰波那契数 2. 题目描述&#xff1a; 泰波那契序列 Tn 定义如下&#xff1a; T0 0, T1 1, T2 1, 且在 n > 0 的条件下 Tn3 Tn Tn1 Tn2 给你整数 n&#xff0c;请返回第 n 个泰波那契数 Tn 的值。 示例 1&#xff1a; 输入&#…

从瀑布模式到水母模式:ChatGPT如何赋能软件研发全流程

&#x1f680;欢迎来到本文&#x1f680; &#x1f349;个人简介&#xff1a;陈童学哦&#xff0c;目前学习C/C、算法、Python、Java等方向&#xff0c;一个正在慢慢前行的普通人。 &#x1f3c0;系列专栏&#xff1a;陈童学的日记 &#x1f4a1;其他专栏&#xff1a;CSTL&…

Flutter——最详细(Scaffold)使用教程

Scaffold简介 相当于界面的主体&#xff08;类似于安卓最外层PhoneWindow&#xff09;&#xff0c;组件的展示都必须依附于它。 使用场景&#xff1a; 每一个界面都是脚手架&#xff0c;通过它来进行架构实现&#xff0c;优美的布局效果。 属性作用appBar顶部的标题栏body显示整…