如何在.NET Core 5 API中实现16GB超大文件上传 现有配置仅支持4GB
16GB大文件上传实现方案
这个需求完全可以实现,你当前配置只能传最大4GB文件,是因为IIS自带的requestLimits节点下maxAllowedContentLength属性为32位无符号整数,参数上限就是4294967295字节(即4GB),无法通过修改该参数突破限制,可选择以下两种方案实现需求:
方案一:分片上传(最稳妥,推荐)
无需修改服务端请求大小限制,兼容性最高,同时支持断点续传,避免网络波动导致16GB文件重传的问题:
- 前端将16GB源文件切分为固定大小的分片(单分片建议设为50MB~200MB),每个分片请求携带三个参数:文件唯一标识、当前分片序号、总分片数
- 服务端接收所有分片后,按照分片序号合并为完整的源文件即可
方案二:改用Kestrel直接托管,支持单请求上传16GB
如果不想修改前端逻辑要求单请求上传,可放弃IIS托管,直接用.NET Core自带的Kestrel服务器托管,Kestrel的请求大小限制为long类型,支持设置超过4GB的数值,调整配置如下:
服务配置调整
services.Configure<FormOptions>(o => { o.ValueLengthLimit = int.MaxValue; // 设置为16GB对应的字节数 o.MultipartBodyLengthLimit = 17179869184; o.MemoryBufferThreshold = int.MaxValue; }); // 配置Kestrel全局请求体上限 builder.WebHost.ConfigureKestrel(options => { options.Limits.MaxRequestBodySize = 17179869184; });
接口实现注意事项
不要使用模型绑定直接接收IFormFile,会导致16GB文件全部缓冲到内存,直接撑爆服务端内存,必须用流式读取直接写入磁盘,示例代码如下:
[HttpPost("upload")] // 也可以加该特性直接禁用当前接口的请求大小限制,无需全局配置Kestrel [DisableRequestSizeLimit] public async Task<IActionResult> Upload() { var boundary = Request.ContentType.Split('=')[1]; var reader = new MultipartReader(boundary, Request.Body); var section = await reader.ReadNextSectionAsync(); while (section != null) { var hasDisposition = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out var disposition); if (hasDisposition && disposition.IsFileDisposition()) { var savePath = Path.Combine("你的本地存储目录", disposition.FileName.Value); await using var writeStream = new FileStream(savePath, FileMode.Create, FileAccess.Write, FileShare.None, bufferSize: 1024 * 1024, useAsync: true); await section.Body.CopyToAsync(writeStream); } section = await reader.ReadNextSectionAsync(); } return Ok(); }
内容的提问来源于stack exchange,提问作者jeegnesh
相关产品推荐
相关产品推荐

