.net core 6.0 mvc js对文件分片上传文件+控制器合并文件保存
js,通过ajax将文件分片提交
//获取文件信息(以上传图片为例) //生成Blob的图片格式 var Imginfo=图片转为Blob格式信息;
//文件上传控制器路径
var upload_url="XXXXXX";
/** * 文件上传入口,进行匹配计算文件上传大小然后上传 * */ function usk_upload_file_in(file) { var l = file.size; var step = _cnf_up_one_set.up_one_length; //获取文件分片总片数 var total_blob_num = Math.ceil(l / step); _cnf_up_one_set._one_total_num = total_blob_num; var _start = 0; var _end = 0; usk_callback(0, ""); _cnf_up_one_set._one_blob_num = 1; usk_upload_file_one(file); } /** * 文件上传,递归调用上传文件片 * */ function usk_upload_file_one(file) { var l = file.size; if (_cnf_up_one_set._one_blob_num > _cnf_up_one_set._one_total_num) { return; } var step = _cnf_up_one_set.up_one_length; _start = (_cnf_up_one_set._one_blob_num - 1) * step; _end = _start + step; if (_end >= l) { _end = l; } _cnf_up_one_set._one_blob_data = usk_cutfile_in(file, _start, _end); usk_upload_file(_cnf_up_one_set._one_blob_data, file); _cnf_up_one_set._one_blob_num++; setTimeout(function () { usk_upload_file_one(file); }, 1); //usk_upload_file_one(file); } /** * 图片切割 * */ function usk_cutfile_in(file, s, e) { //文件分隔 var file_blob = file.slice(s, e); _cnf_up_one_set._one_start = s; _cnf_up_one_set._one_end = e; return file_blob; };
/** * 进行文件上传 * */ function usk_upload_file(blob, file) { //创建FormData对象 //FormData对象用于存储待上传的文件和相关信息。你需要将选定的Blob文件与该对象进行关联,以便在发送XHR请求时传递给服务器。 var form_data = new FormData(); form_data.append('file', blob); var ruladd2 = "&size=" + file.size + "&index=" + _cnf_up_one_set._one_blob_num + "&total=" + _cnf_up_one_set._one_total_num + "&fname=" + encodeURI(file.name); ruladd2 += "&guid=" + _cnf_up_one_set._up_one_guid ruladd2 = upload_url + ruladd2; $.ajax({ url: ruladd2, type: 'post', async: false, dataType: "json",//返回json数据类型 data: form_data, contentType: false,//似乎会默认转为:multipart/form-data processData: false, success: function (data) { var result = data.result; if (result < 0) { _layer.close(_cnf_up_one_set._one_loading_id); _layer.msg(data.msg, { icon: 2, time: 2000 }); } //#region 1.上传中 if (result == 1) { //上传中 // 进度条和状态设置 if (_cnf_up_one_set._one_total_num == 1) { progress = 100; } else { progress = (Math.min(100, (_cnf_up_one_set._one_blob_num / _cnf_up_one_set._one_total_num) * 100)).toFixed(2); } usk_callback(progress, "上传中"); form_data = ""; } //#endregion //#region 2.文件上传完成 if (result == 0) { _layer.close(_cnf_up_one_set._one_loading_id); //上传完成 _cnf_up_one_set._one_is_stop = 1; // 进度条 progress = 100; //每次清空 form_data = ""; usk_callback(progress, data.msg); } //#endregion }, error: function (data) { _layer.close(_cnf_up_one_set._one_loading_id); usk_callback(-1, "系统未知错误"); return; } }) }
控制器
/// <summary> /// 获取上传文件 /// </summary> /// <returns></returns> public IActionResult UploadFileBlock([FromForm(Name = "file")] List<IFormFile> files) { //获取上传文件 //获取上传文件的基本信息 URLTools.UsURLToObjectOnly(FileBlob_entity, false); if (files.Count > 0) { //保存至分片文件夹 //临时保存分块的目录 _apiresult = SaveFile(files[0], FileBlob_entity); } USTemp = UsJsonTools.SerializeObject(_apiresult); return Content(USTemp); }
/// <summary> /// 上传保存文件 /// </summary> /// <param name="file">文件</param> /// <param name="FileBlob_entity"></param> public APIResult SaveFile(IFormFile file, FileBlob FileBlob_entity) { string savepath = ""; //判断是否存在,如果不存在自动创建 物理路径 var filepath = Directory.GetCurrentDirectory(); //文件存储路径 var sSavePath = ""; //文件分片临时存储文件夹 //var genurl = System.AppDomain.CurrentDomain.BaseDirectory; string genurl = ToolsBasic.UsPath(""); string sBaseDir = genurl+ "/upload/headImg/" + FileBlob_entity.guid; if (!Directory.Exists(sBaseDir)) { Directory.CreateDirectory(sBaseDir); } //保存文件 //本地保存路径 sSavePath = sBaseDir + "/" + FileBlob_entity.guid + FileBlob_entity.index; //判断文件的存在 var sese = System.IO.File.Exists(sSavePath); if (System.IO.File.Exists(sSavePath)) { //存在文件 } else { //不存在文件、保存本地 using (FileStream fs = new FileStream(sSavePath, FileMode.Create)) { file.CopyTo(fs); fs.Flush(); } } _apiresult.result = 1;//上传中 //最后一片上传成功进行合并 if (FileBlob_entity.index.Ext_ToInt() == FileBlob_entity.total.Ext_ToInt()) { savepath = "/upload/headImg/" + DateTime.Now.ToString("yyyyMM"); if (!Directory.Exists(genurl+savepath)) { Directory.CreateDirectory(genurl + savepath); } savepath = savepath + "/I-"+DateTime.Now.ToString("yyyyMMddhhmmss")+".jpg"; MergeFileAsync(sBaseDir, genurl + savepath); _apiresult.result = 0;//上传完成 } _apiresult.msg = savepath; _apiresult.data = FileBlob_entity; return _apiresult; } /// <summary> /// 合并分片的文件 /// </summary> /// <param name="sBaseDir">临时文件夹</param> private async Task MergeFileAsync(string sBaseDir, string savepath) { //获得下面的所有文件 var files = Directory.GetFiles(sBaseDir); //最终的文件名(demo中保存的是它上传时候的文件名,实际操作肯定不能这样) using (var fs = new FileStream(savepath, FileMode.Create)) { //排一下序,保证从0-N Write var fileParts = files.OrderBy(x => x.Length).ThenBy(x => x); foreach (var part in fileParts) { var bytes = await System.IO.File.ReadAllBytesAsync(part); await fs.WriteAsync(bytes, 0, bytes.Length); bytes = null; //删除分块 System.IO.File.Delete(part); } await fs.FlushAsync(); fs.Close(); //删除临时文件夹和分片文件 Directory.Delete(sBaseDir); } }
/// <summary> /// 文件分片上传信息 /// </summary> public class FileBlob { /// <summary> /// 当前上传文件第几片 /// </summary> public string index { get; set; } /// <summary> ///文件总大小 /// </summary> public string size { get; set; } /// <summary> /// 文件总片数 /// </summary> public string total { get; set; } //文件名 public string fname { get; set; } /// <summary> /// guid /// </summary> public string guid { get; set; } }
执行过程;
上传时若文件大于设置的文件片大小,js进行切割,后端将其临时存在一个文件夹内;

待全部文件片上传完后,将临时文件夹里的文件合并,然后删除这个临时文件

文件片段上传成功后删除放置文件片的临时文件

查看目录,图片已经上传成功

遇到问题:
.net core 6.0 mvc上传文件位置
主文件夹下的\bin\Debug\net6.0

文件访问不了问题
在startup配置
#region 让upload文件夹可以外部访问 string sUploadPath = "/upload"; string sFDir =ToolsBasic.UsPath(sUploadPath); if (!Directory.Exists(sFDir)) { Directory.CreateDirectory(sFDir); } app.UseStaticFiles(new StaticFileOptions { FileProvider = new PhysicalFileProvider(sFDir), RequestPath = sUploadPath }); #endregion
public static string UsPath(string sPath) { //程序集的基目录的文件路径。E:\文件PPT\文件PPT\oneself\SystemProjectOne\SystemProjectOne\SystemProjectOne\bin\Debug\net6.0\ string baseDirectory = AppContext.BaseDirectory; string text = sPath; text = Path.Combine(baseDirectory + sPath); return Path.GetFullPath(text); }

参考文献:
https://www.cnblogs.com/GoatRoc/p/16192506.html
https://blog.csdn.net/allenwdj/article/details/103383460
本文来自博客园,作者:じ逐梦,转载请注明原文链接:https://www.cnblogs.com/ZhuMeng-Chao/p/17537487.html

浙公网安备 33010602011771号