A, .Net Core block upload files
First, the front-end implementation
@* For more information on enabling MVC for empty projects, visit http://go.microsoft.com/fwlink/?LinkID=397860 *@ @{ ViewData["Title"] = "Index"; Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>Index</title> <link href="https://cdn.bootcss.com/webuploader/0.1.1/webuploader.css" rel="stylesheet"> <link href="https://cdn.bootcss.com/twitter-bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <script type="text/javascript"> var UploadPath = ""; //开始上传 function UploadStart() { var file = $("#path")[0].files[0]; AjaxFile(file, 0 ); } function AjaxFile (File, I) { var name = file.name, // file name size = file.size, // total size = 2 * 1024 * shardSize 1024, shardSize = 2 * 1024 * 1024 , / / in a 2MB fragment shardCount = Math.ceil (size / shardSize); // total number of pieces IF (I > = shardCount) { return ; } //Calculated for each one of the starting and ending position var Start = I * shardSize, End = Math.min (size, Start + shardSize); // Construct a form, FormData is added HTML5 var form = new new the FormData (); form .append ( " Data " , file.slice (Start, End)); // Slice a method for cutting out a portion of a file form.append ( " the lastModified " , file.lastModified); form.append ( " fileName " , name ); form.append ( "Total " , shardCount); // total number of pieces form.append ( " index " , I + . 1 ); // this is the first few sheets UploadPath = file.lastModified // Ajax submission $ .ajax ({ URL: " / the Upload / UploadFile " , of the type: " POST " , the Data: form, the async: to true , // asynchronous processData: false ,// very important, do not tell jquery to form processing contentType: false , // very important, designated to form the correct Content-Type is false to Success: function (the Result) { IF (the Result ! = Null ) { i = the Result. Number ++ ; var NUM = Math.ceil (I * 100 / shardCount); $ ( " #output " ) .text (NUM + ' % ' ); AjaxFile(file, i); if (result.mergeOk) { var filepath = $("#path"); filepath.after(filepath.clone().val("")); filepath.remove();//清空input file $('#upfile').val('请选择文件'); alert("success!!!"); } } } }); } </script> </head> <body> <div class="row" style="margin-top:20%"> <div class="col-lg-4"></div> <div class="col-lg-4"> <input type="text" value="请选择文件" size="20" name="upfile" id="upfile" style="border:1px dotted #ccc"> <input type="button" value="浏览" onclick="path.click()" style="border:1px solid #ccc;background:#fff"> <input type="file" id="path" style="display:none" multiple="multiple" onchange="upfile.value=this.value"> <br /> <span id="output">0%</span> <button type="button" id="file" onclick="UploadStart()" style="border:1px solid #ccc;background:#fff">开始上传</button> </div> <div class="col-lg-4"></div> </div> </body> </html>
The main idea here is to use the method html5 File api slice of the document block,
Then a new FormData () object is used to store data files, then that is the recursive call AjaxFile method until the upload is complete.
Background Code:
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; namespace WebApplication2.Controllers { public class UploadController : Controller { public IActionResult Index() { return View(); } [HttpPost] public async Task<ActionResult> UploadFile() { var data = Request.Form.Files["data"]; string lastModified = Request.Form["lastModified"].ToString(); var total = Request.Form["total"]; var fileName = Request.Form["fileName"]; var index = Request.Form["index"]; string temporary = Path.Combine(@"D:\浏览器", lastModified);//临时保存分块的目录 try { if (!Directory.Exists(temporary)) Directory.CreateDirectory(temporary); string filePath = Path.Combine(temporary, index.ToString()); if (!Convert.IsDBNull(data)) { await Task.Run(() => { FileStream fs = new FileStream(filePath, FileMode.Create); data.CopyTo(fs); fs.Close(); }); } bool mergeOk = false; if (total == index) { mergeOk = await FileMerge(lastModified, fileName); } Dictionary<string, object> result = new Dictionary<string, object>(); result.Add("number", index); result.Add("mergeOk", mergeOk); return Json(result); } catch (Exception ex) { Directory.Delete(temporary);//Delete a folder the throw EX; } } public the async the Task < BOOL > FileMerge ( String the lastModified, String fileName) { BOOL OK = to false ; the try { var Temporary = Path.Combine ( @ " D: \ Browser " , the lastModified); / / temporary folder fileName = Request.Form [ " fileName " ]; // filename String FileExt = Path.GetExtension (fileName); // get the file suffix var Files = Directory.GetFiles (the Temporary); // get all of the following documents var finalPath = Path.Combine ( @ " D: \ Browser " , DateTime.Now.ToString ( " YYMMDDHHMMSS " ) + FileExt); // final file name (saved in the demo it is time to upload the file name, the actual operation is certainly not so) var FS = new new the FileStream (finalPath, FileMode.Create); foreach ( var Part in files.OrderBy (the X-=> x.length ) .ThenBy (X => X)) // row at order to ensure that the Write from the N-0 { var bytes = System.IO.File.ReadAllBytes (Part); the awaitfs.WriteAsync (bytes, 0 , bytes.Length); bytes = null ; System.IO.File.Delete (Part); // delete the block } fs.Close (); Directory.Delete (Temporary); // Delete folder OK = to true ; } the catch (Exception EX) { the throw EX; } return OK; } } }