• .net core 上传大文件


    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(20971520)]
            [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 = 84975;//写出缓冲区大小
                int writeCount = 0;
                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 = 0;
                    while ((readCount = await stream.ReadAsync(byteArr, 0, byteArr.Length)) > 0)
                    {
                        await fileStream.WriteAsync(byteArr, 0, 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;
    });

  • 相关阅读:
    Jenkins自动化Harbor安装与基本使用
    20212917于欣月 202120222 《网络攻防实践》第一周作业
    nfs挂载失败
    .NET CORE .NET 5 6在华为arm 鲲鹏服务器运行
    EF CORE 2.0升级到6.0 记录
    Go语言使用gorm对MySQL进行性能测试
    Go自定义DNS解析器负载均衡实践
    基于爬虫的测试自动化经验分享
    Java&Go高性能队列之channel性能测试
    Jira API的六种传参方式
  • 原文地址:https://www.cnblogs.com/zhanghm1/p/12890815.html
Copyright © 2020-2023  润新知