.netcore c# 文件上传大致分为两种方式,流式缓冲式,前者适用于大文件上传,后者则适用于小文件上传,具体区别如下。

  • 缓冲:通过模型绑定先把整个文件保存到内存,然后我们通过IFormFile得到Stream,优点是效率高,缺点对内存要求大,适用于小文件上传。
  • 流式处理:直接读取请求体装载后的Section 对应的stream 直接操作strem即可,无需把整个请求体读入内存;适用于大文件上传。

本文只讲通过文件流上传大文件,小文件上传可以参考我的这篇文章 文件上传接口实现 - 实用工具_软件教程_.net_c#-有码挺好个人博客 (cisharp.com)

/// <summary>
        /// 大文件上传,参数“softPackage”,可自定义
        /// </summary>
        /// <returns></returns>
        [HttpPost("UploadSoftPackage")]
        [RequestSizeLimit(419430400)/*文件大小上限,400M,可自定义*/]
        public async Task<HttpResponseMessage> UploadSoftPackage()
        {
            try
            {
                //获取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();
                var webRoot = _hostingEnvironment.WebRootPath/*IWebHostEnvironment,用于获取网站、API根目录*/;
                bool flag = false;
                long fileLen = 0;
                List<string> extList = new List<string>() { ".exe", ".apk", ".zip", ".rar" };
                var savePath = string.Empty;
                //读取section
                while (section != null)
                {
                    var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out var contentDisposition);
                    if (hasContentDispositionHeader)
                    {
                        if (contentDisposition.Name == "softPackage")
                        {
                            var fileName = contentDisposition.FileName.Value;
                            var fileExt = Path.GetExtension(fileName);
                            if (extList.Contains(fileExt))
                            {
                                flag = true;
                                var dir = Path.Combine(webRoot, "SoftPackage");
                                if (!Directory.Exists(dir))
                                {
                                    Directory.CreateDirectory(dir);
                                }
                                savePath = $"/SoftPackage/{fileName}";
                                fileLen = await WriteFileAsync(section.Body, Path.Combine(dir, fileName));
                            }
                            else
                            {
                                return JsonManager.SimpleCustResponse("unsupported media type");
                            }
                        }
                    }
                    section = await reader.ReadNextSectionAsync();
                }
                if (!flag)
                {
                    return JsonManager.SimpleCustResponse("softPackage is require");
                }
                else
                {
                    if (fileLen > 0)
                    {
                        return JsonManager.ReturnSuccessResponse(savePath);
                    }
                    else
                    {
                        return JsonManager.SimpleCustResponse("file upload failed");
                    }
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex.ToString());
                return JsonManager.SimpleStatusResponse(ResultCode.OPERATE_FAILED);

            }
        }

        /// <summary>
        /// 写文件导到磁盘
        /// </summary>
        /// <param name="stream">流</param>
        /// <param name="path">文件保存路径</param>
        /// <returns></returns>
        private async Task<int> WriteFileAsync(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;
        }
最后修改:2022 年 11 月 26 日
如果觉得我的文章对你有用,请随意赞赏