缓冲和流式传输是上传文件的两种常用方案,这里主要演示流式传输。
1.Net Core MVC Form提交方式:
前端页面 form表单提交:
1 <form id="uploadForm"> 2 图片上传: <input type="file" name="file" multiple value="选择" onchange="doUpload()" id="ajaxfile" /> 3 </form> 4 <script type="text/javascript"> 5 //图片上传 6 function doUpload() 7 { 8 var formData = new FormData($("#uploadForm")[0]); 9 $.ajax({ 10 url: '@Url.Action("FileSave", "FileUpload")', 11 type: 'POST', 12 data: formData, 13 async: false, 14 cache: false, 15 contentType: false, 16 processData: false, 17 success: function (returndata) { 18 //成功后执行的方法 19 }, 20 error: function (returndata) { 21 //上传失败执行的方法 22 } 23 }); 24 } 25 </script>
后端方法:
采用的流式处理,请求收到文件,然后应用直接处理或者保存。这种传输无法提高性能,但优点是可降低上传时对内存或磁盘空间的需求。
通过流(stream)把请求收到的文件拷贝到系统指定的文件中。
1 2 [HttpPost] 3 public async Task<IActionResult> FileSave() 4 { 5 //获取Form提交的文件 6 var files = Request.Form.Files; 7 long size = files.Sum(f => f.Length); 8 string webRootPath = _hostingEnvironment.WebRootPath; //物理路径 9 string contentRootPath = _hostingEnvironment.ContentRootPath; 10 string showfilePath = ""; 11 foreach (var formFile in files) 12 { 13 if (formFile.Length > 0) 14 { 15 int count = formFile.FileName.Split('.').Length; 16 string fileExt = formFile.FileName.Split('.')[count - 1]; //文件扩展名,不含“.” 17 long fileSize = formFile.Length; //获得文件大小,以字节为单位 18 string newFileName = System.Guid.NewGuid().ToString() + "." + fileExt; //随机生成新的文件名 19 #region 文件夹不存在则创建 20 var filePath = webRootPath + "/upload"; 21 if (!Directory.Exists(filePath)) 22 { 23 Directory.CreateDirectory(filePath); 24 } 25 #endregion 26 #region 文件不存在则新建 27 filePath = webRootPath + "/upload/" + newFileName; 28 showfilePath = "upload/" + newFileName; 29 FileHelper.CreateFile(filePath); 30 #endregion 31 //把上传的图片复制到指定的文件中 32 using (var stream = new FileStream(filePath, FileMode.Create)) 33 { 34 await formFile.CopyToAsync(stream); 35 } 36 } 37 } 38 return Ok(new { count = files.Count, savepath = showfilePath }); 39 }
2.基于Base64的方式
前端用Vue提交,调用后端接口
vue提交用FormData方式,params方提交的参数会放到Url末尾,导致过长超出,这里用FormData的方式提交
提交时传递的参数要通过FormData对象来添加
Vue提交方法:
1 //上传图片 2 3 afterRead(file) { 4 // 此时可以自行将文件上传至服务器 5 let obj={}; 6 var imgurl=file.content 7 //需要将文件的地址 需要去掉base64头部标签 这里简单用replace替换 8 imgurl = imgurl.replace("data:image/jpeg;base64,", ""); 9 //获取图片的格式 10 var Img=file.file.name.split('.')[1] 11 12 //创建formdata对象 传递参数 13 var formdata=new FormData(); 14 formdata.append("fileBase64",imgurl);//添加一条数据 15 formdata.append("fileExt",Img);//添加一条数据 16 17 //ajax调用接口,ajax的参数配置 18 this.$ajax({ 19 method: 'post', 20 dataType:'json', 21 url: "http://*****/FileUpload/UploadBase64", 22 contentType : false,// 告诉jQuery不要去设置Content-Type请求头 23 processData: false,// 告诉jQuery不要去处理发送的数据, 24 beforeSend : function(req) { 25 req.setRequestHeader('Content-Type', 'application/json'); ///加这一行解决问题 26 }, 27 data: formdata 28 }).then(res=>{ 29 //图片上传成功后 执行的操作 30 var msg=res.data.msg 31 32 }).catch(error =>{ 33 console.log(error) 34 }) 35 },
后端方法:原理和1基本相同
1 [HttpPost] 2 3 public string UploadBase64(string fileBase64,string fileExt) 4 { 5 TableData data = new TableData(); 6 byte[] bytes = ToBytes_FromBase64Str(fileBase64); 7 //var fileExtension = Path.GetExtension(fileName); 8 9 string webRootPath = _hostingEnvironment.WebRootPath; 10 string newFileName = System.Guid.NewGuid().ToString() + "." + fileExt; //随机生成新的文件名 11 12 var filePath = webRootPath + "/upload"; 13 var RetfilePath = "upload/" + newFileName; 14 if (!Directory.Exists(filePath)) 15 { 16 Directory.CreateDirectory(filePath); 17 } 18 filePath = webRootPath + "/upload/" + newFileName; 19 try 20 { 21 data.code = 200; 22 FileStream fs = new FileStream(filePath, FileMode.CreateNew); 23 fs.Write(bytes, 0, bytes.Length); 24 fs.Close(); 25 data.msg = RetfilePath; 26 } 27 catch (Exception ex) 28 { 29 data.code = 500; 30 data.msg = "newFileName:"+ newFileName+"Error:"+ex.Message; 31 } 32 return JsonHelper.Instance.Serialize(data); 33 }
附:FileHelper类 和TableData类
1 public static class FileHelper 2 { 3 4 /// <summary> 5 /// 拷贝文件 6 /// </summary> 7 /// <param name="orignFile">原始文件</param> 8 /// <param name="newFile">新文件路径</param> 9 public static void FileCoppy(string orignFile, string newFile) 10 { 11 if (string.IsNullOrEmpty(orignFile)) 12 { 13 throw new ArgumentException(orignFile); 14 } 15 if (string.IsNullOrEmpty(newFile)) 16 { 17 throw new ArgumentException(newFile); 18 } 19 System.IO.File.Copy(orignFile, newFile, true); 20 } 21 /// <summary> 22 /// 删除文件 23 /// </summary> 24 /// <param name="path">路径</param> 25 public static void FileDel(string path) 26 { 27 if (string.IsNullOrEmpty(path)) 28 { 29 throw new ArgumentException(path); 30 } 31 System.IO.File.Delete(path); 32 } 33 /// <summary> 34 /// 移动文件 35 /// </summary> 36 /// <param name="orignFile">原始路径</param> 37 /// <param name="newFile">新路径</param> 38 public static void FileMove(string orignFile, string newFile) 39 { 40 if (string.IsNullOrEmpty(orignFile)) 41 { 42 throw new ArgumentException(orignFile); 43 } 44 if (string.IsNullOrEmpty(newFile)) 45 { 46 throw new ArgumentException(newFile); 47 } 48 System.IO.File.Move(orignFile, newFile); 49 } 50 //创建路径 51 public static void CreatePath(string FilePath) 52 { 53 if (!Directory.Exists(FilePath)) 54 { 55 Directory.CreateDirectory(FilePath); 56 } 57 } 58 //创建文件 59 public static void CreateFile(string FilePath) 60 { 61 if (!File.Exists(FilePath)) 62 { 63 FileStream fs = File.Create(FilePath); 64 fs.Close(); 65 } 66 } 67 }
1 public class TableData 2 { 3 /// <summary> 4 /// 状态码 5 /// </summary> 6 public int code; 7 /// <summary> 8 /// 操作消息 9 /// </summary> 10 public string msg; 11 /// <summary> 12 /// 总记录条数 13 /// </summary> 14 public int count; 15 16 /// <summary> 17 /// 数据内容 18 /// </summary> 19 public dynamic data; 20 public TableData() 21 { 22 code = 200; 23 msg = "加载成功"; 24 25 } 26 }
演示效果如下: