using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using DiuDiuTemplate.Domain.WebHelpers.Base;
using DiuDiuTemplate.Infrastructure.Common.Helpers;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Net.Http.Headers; namespace DiuDiuTemplate.UserApi.Controllers
{
public class FileUpLoadController : ApiControllerBase
{
private IWebHostEnvironment _webhostEnv; public FileUpLoadController(IWebHostEnvironment webhostEnv)
{
_webhostEnv = webhostEnv;
} /// <summary>
/// 上传文件到API服务器 较小的文件上传 20M
/// </summary>
/// <returns>返回文件的saveKeys</returns>
[HttpPost]
[RequestSizeLimit()]
[AllowAnonymous]
public async Task<List<string>> UploadFile(List<IFormFile> files)
{
List<string> saveKeys = new List<string>(); foreach (var formFile in files)
{
//相对路径
string saveKey = GetRelativePath(formFile.FileName); //完整路径
string path = GetAbsolutePath(saveKey);
await WriteFileAsync(formFile.OpenReadStream(), path);
saveKeys.Add(saveKey);
}
return saveKeys;
}
/// <summary>
/// 大文件上传到API服务器
/// 流式接收文件,不缓存到服务器内存/// </summary>
/// <att name="DisableRequestSizeLimit">不限制请求的大小</att>
/// <returns>返回文件的saveKeys</returns>
[HttpPost]
[Route("BigFileUpload")]
[DisableRequestSizeLimit]
[AllowAnonymous]
public async Task<List<string>> BigFileUpload()
{
List<string> saveKeys = new List<string>(); //获取boundary
var boundary = HeaderUtilities.RemoveQuotes(MediaTypeHeaderValue.Parse(Request.ContentType).Boundary).Value;
//得到reader
var reader = new MultipartReader(boundary, HttpContext.Request.Body); var section = await reader.ReadNextSectionAsync(); //读取 section 每个formData算一个 section 多文件上传时每个文件算一个 section
while (section != null)
{
var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out var contentDisposition);
if (hasContentDispositionHeader)
{
if (contentDisposition.IsFileDisposition())
{
//相对路径
string saveKey = GetRelativePath(contentDisposition.FileName.Value);
//完整路径
string path = GetAbsolutePath(saveKey); await WriteFileAsync(section.Body, path);
saveKeys.Add(saveKey);
}
else
{
string str = await section.ReadAsStringAsync();
}
}
section = await reader.ReadNextSectionAsync();
}
return saveKeys; }
/// <summary>
/// 写文件导到磁盘
/// </summary>
/// <param name="stream">流</param>
/// <param name="path">文件保存路径</param>
/// <returns></returns>
private static async Task<int> WriteFileAsync(System.IO.Stream stream, string path)
{
const int FILE_WRITE_SIZE = ;//写出缓冲区大小
int writeCount = ;
using (FileStream fileStream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Write, FILE_WRITE_SIZE, true))
{
byte[] byteArr = new byte[FILE_WRITE_SIZE];
int readCount = ;
while ((readCount = await stream.ReadAsync(byteArr, , byteArr.Length)) > )
{
await fileStream.WriteAsync(byteArr, , readCount);
writeCount += readCount;
}
}
return writeCount;
} /// <summary>
/// 获取相对路径
/// </summary>
/// <param name="fileName"></param>
/// <returns></returns>
private string GetRelativePath(string fileName)
{
string str1 = CommonHelper.GetGuid().Replace("-", "");
int start = fileName.LastIndexOf('.');
//相对路径
return $"/upload/{DateTime.Now.Year}/{DateTime.Now.Month}/{DateTime.Now.Day}/{str1}{fileName.Substring(start, fileName.Length - start)}"; }
/// <summary>
/// 获取完整路径
/// </summary>
/// <param name="relativePath"></param>
/// <returns></returns>
private string GetAbsolutePath(string relativePath)
{
//完整路径
string path = Path.Join(_webhostEnv.WebRootPath, relativePath); string directoryPath = Path.GetDirectoryName(path);
if (!Directory.Exists(directoryPath))
{
Directory.CreateDirectory(directoryPath);
} return path; }
}
}

小文件上传和大文件上传;

最后记得要添加静态文件中间件

app.UseStaticFiles();

API默认没有这个中间件

还可以设置一些上传大小的限制,这个只是程序的配置,如果部署到IIS等,还需要修改IIS的上传文件限制,这里只实现代码部分;

  

services.Configure<FormOptions>(x =>
{
  x.ValueLengthLimit = int.MaxValue;
  x.MultipartBodyLengthLimit = int.MaxValue;
  x.MultipartHeadersLengthLimit = int.MaxValue;
});

.net core 上传大文件的更多相关文章

  1. ASP.NET Core 上传大文件无法接收的问题

    解决办法:在API项目中配置 1. 在 web.config 文件中 <system.webServer>里加入 <security> <requestFiltering ...

  2. asp.net core流式上传大文件

    asp.net core流式上传大文件 首先需要明确一点就是使用流式上传和使用IFormFile在效率上没有太大的差异,IFormFile的缺点主要是客户端上传过来的文件首先会缓存在服务器内存中,任何 ...

  3. 日常采坑:.NetCore上传大文件

    一..NetCore上传大文件 .NetCore3.1 webapi 本地测试上传时,遇到一个坑,大点的文件直接失败,根本不走控制器方法. 二.大文件上传配置 IFormFile方式,vs IIS E ...

  4. 批量上传文件或者上传大文件时 gateWay报错DataBufferLimitException: Exceeded limit on max bytes to buffer : 262144

    一.描述 最近在批量上传文件时网关出现了异常,后面发现上传大文件也会出现文件超过256发生异常,异常信息如下: org.springframework.core.io.buffer.DataBuffe ...

  5. [Asp.net]Uploadify上传大文件,Http error 404 解决方案

    引言 之前使用Uploadify做了一个上传图片并预览的功能,今天在项目中,要使用该插件上传大文件.之前弄过上传图片的demo,就使用该demo进行测试.可以查看我的这篇文章:[Asp.net]Upl ...

  6. php 上传大文件配置upload_max_filesize和post_max_size选项

    php 上传大文件配置upload_max_filesize和post_max_size选项 (2014-04-29 14:42:11) 转载▼ 标签: php.ini upload _files[f ...

  7. PHP上传大文件 分割文件上传

    最近遇到这么个情况,需要将一些大的文件上传到服务器,我现在拥有的权限是只能在一个网页版的文件管理系统来进行操作,可以解压,可以压缩,当然也可以用它来在线编辑.php文件. 文件有40M左右,但是服务器 ...

  8. ASP.NET上传大文件的问题

    原文:http://www.cnblogs.com/wolf-sun/p/3657241.html?utm_source=tuicool&utm_medium=referral 引言 之前使用 ...

  9. php 上传大文件主要涉及配置upload_max_filesize和post_max_size两个选项

    php 上传大文件主要涉及配置 upload_max_filesize 和post_max_size两个选项   今天在做上传的时候出现一个非常怪的问题,有时候表单提交可以获取到值,有时候就获取不到了 ...

随机推荐

  1. oracle常用字符函数

    字符函数: concat:(字符连接函数) --字符连接 select concat('con','cat') from dual; select 'co'||'nc'||'at' from dual ...

  2. python 读取矢量文件

    #导入包 from osgeo import ogr #打开文件(False - read only, True - read/write) filename = "文件名.shp" ...

  3. PHP导出excel文件,第二步先实现自写二维数组加入模板excel文件后导出

    今天主要研究数据加入EXCEL并导出的问题,先不从数据库提取数据导出,自己先写一个二维数组,然后遍历二维数组写入excel模板中导出,首先根据模板excel的内容书写对应的二维数组 $arr=arra ...

  4. Java并发编程实战 04死锁了怎么办?

    Java并发编程文章系列 Java并发编程实战 01并发编程的Bug源头 Java并发编程实战 02Java如何解决可见性和有序性问题 Java并发编程实战 03互斥锁 解决原子性问题 前提 在第三篇 ...

  5. Spring DI使用详解

    Spring DI使用详解 一.介绍 DI的定义:依赖注入,为类里面的属性设值.例如,我们之前的setName方法就是在为name属性设值. IOC与DI的关系:IOC进行对象的创建,DI进行值的注入 ...

  6. python语法学习第七天--文件

    打开文件:open() 使用 open() 方法一定要保证关闭文件对象,即调用 close() 方法. open(file, mode='r', buffering=-1, encoding=None ...

  7. 设计模式之GOF23原型模式02

    利用序列化和反序列化完成深复制 ByteArrayOutputStream bos=new ByteArrayOutputStream();  ObjectOutputStream oos=new O ...

  8. [hdu4599]期望DP

    思路:容易知道G(x)=6x,H(x)=6F(x).此题的关键是求出F(x)的通项,要求F(x)的通项,先建立递推式:F(x)=1/6 * (F(x-1)+1) + 5/6 * (F(x-1)+1+F ...

  9. sqli-labs之Page-4

    第五十四关 题目给出了数据库名为challenges. 这一关是依旧字符型注入,但是尝试10次后,会强制更换表名等信息.所以尽量在认真思考后进行尝试 爆表名 ?id=-1' union select ...

  10. HTML学习——day1

    HTML是一种用于创建网页的标准标记语 注意:对于中文网页需要使用<meta charset=''utf-8''>声明编码,否则会出现乱码. HTML标签 <标签>内容< ...