后端实现大文件分片上传

项目框架 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.hqwc.cn/news/151013.html

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

相关文章

docker - DockerFile 编写 指令

文章目录 前言docker - DockerFile 编写 指令1. FROM2. MAINTAINER3. RUN4. CMD5. LABEL6. EXPOSE7. ENV8. ADD9. COPY10. ENTRYPOINT11. VOLUME12. USER13. WORKDIR14. ARG15. ONBUILD16. STOPSIGNAL 前言 如果您觉得有用的话&#xff0c;记得给博主点个赞&#xff0c;评论&am…

如何使用Abaqus进行摩擦生热仿真

Abaqus除了可以对结构进行强度分析&#xff0c;同样也有强大的固体传热分析功能&#xff0c;下面通过一个简单的实例演示Abaqus的双向热固耦合分析。 因为本案例涉及物体表面辐射&#xff0c;因此需要定义绝对零度和输入史蒂夫-波兹曼常数&#xff0c;如下&#xff1a; 本次分…

B链圆桌派 — 创新的去中心化存储网络 BNB GREENFIELD 主网上线

B链圆桌派 主題: BNB GREENFIELD主网上线 - 创新的去中心化资料储存网路 日期: 10/19, 8 pm utc8 頻道&#xff1a; BNB Chain 华语电报群 ○ AMA环节 ○ BNB GREENFIELD主网上线 一、回复主持人问题 嘉宾回答主持人提出的问题。本环节请大家保持安静&#xff0c;专注嘉宾…

一文搞懂 MineCraft 服务器启动操作和常见问题 2023年10月

文章目录 前言1. 新建文件夹2. 创建 bat 文件3. 编辑 bat 文件4. 启动服务器5. 恭喜完成 文章持续更新中&#xff0c;如果你有问题可以通过 qq 1317699264 获取免费协助&#xff0c;解决的问题将会被更新到本文章中 前言 无论你是使用服务端整合包&#xff0c;还是从上一篇我的…

为虚拟网络提供敏捷负载均衡:Everoute LB 特性解读

为了保证应用系统的可用性&#xff0c;同时避免并发访问导致后端服务器出现性能瓶颈&#xff0c;不少用户都通过负载均衡技术优化流量分发。随着虚拟化平台下用户业务规模的持续扩大&#xff0c;虚拟化网络的数据访问量也不断增加&#xff0c;而传统负载均衡通常通过硬件负载均…

漫谈广告机制设计 | 混排:广告与自然结果的交锋博弈(2)

话说前文&#xff0c;在彼此不同的利益面前&#xff0c;自然侧和广告侧在混排战场展开了一番较量&#xff0c;一个浑水摸鱼&#xff0c;一个暗渡陈仓。最终双方不得不坐下来&#xff0c;为了平台整体的利益&#xff0c;一起谈谈各自的诉求&#xff0c;商讨一下解决方案。 第三…

一个比较特别的串口工具

这是08年写的一个 并网带电池逆变器 的通讯工具&#xff0c;和普通的串口调试器相比&#xff0c;多了一个【脚本】功能。能够通过【脚本】完成通讯测试。 PC发给DSP的01命令 01 10 1B 00 CF A3 00 00 90 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 电…

【Linux】虚拟机部署与发布J2EE项目(Windows版本)

【Linux】虚拟机部署与发布J2EE项目&#xff08;Windows版本&#xff09; 1.将Java项目部署到虚拟机&#xff08;Virtual Machine&#xff09;有以下好处&#xff1a;2.单机项目1.将项目共享到虚拟机2.解压并将war包放入tomcat3.运行tomcat并查看该项目的数据库配置4.数据库导入…

创新领航 | 竹云参编《基于区块链的数据资产评估实施指南》正式发布!

10月25日&#xff0c;由深圳数宝数据服务股份有限公司和深圳职业技术大学提出&#xff0c;中国科学院深圳先进技术研究院、中国电子技术标准化研究院、中国&#xff08;天津&#xff09;自由贸易试验区政策与产业创新发展局、网络空间治理与数字经济法治&#xff08;长三角&…

【LeetCode每日一题合集】2023.10.16-2023.10.22(只出现一次的数字Ⅲ)

文章目录 260. 只出现一次的数字 III⭐&#xff08;异或&#xff09;&#x1f402;2652. 倍数求和解法1——枚举模拟解法2—— O ( 1 ) O(1) O(1)容斥原理相似题目——1201. 丑数 III&#xff08;二分查找容斥原理&#xff09; 2530. 执行 K 次操作后的最大分数解法1——贪心优…

ActiveMQ消息中间件简介

一、ActiveMQ简介 ActiveMQ是Apache出品&#xff0c;最流行的&#xff0c;能力强劲的开源消息总线。ActiveMQ是一个完全支持JMS1.1和J2EE1.4规范的JMS Provide实现。尽管JMS规范出台已经是很久的事情了&#xff0c;但是JMS在当今的J2EE应用中仍然扮演这特殊的地位。 二、Active…

Linux高性能服务器编程——ch8笔记

第8章 高性能服务器程序框架 8.1 服务器模型 服务器启动后&#xff0c;首先创建一个&#xff08;或多个&#xff09;监听socket&#xff0c;并调用bind函数将其绑定到服务器感兴趣的端口&#xff0c;然后调用listen函数等待客户连接。服务器稳定运行之后&#xff0c;客户端就可…