asp.net core分塊上傳檔案樣本

來源:互聯網
上載者:User
寫完asp.net多檔案上傳後,感覺這種上傳還是有很多缺陷,於是。。。(省略一萬字,不廢話)。這裡我沒用傳統的asp.net,而選擇了開源的asp.net core,原因很簡單,.net core是.net新的開始,更是.net和.net開發人員的未來,希望.net發展越來越好(大家的工資越來越高(●ˇ∀ˇ●))。

1.前端的實現:

1).html: 

<html><head>  <meta name="viewport" content="width=device-width" />  <title>Index</title>  <link href="/lib/bootstrap/dist/css/bootstrap.css" rel="external nofollow" rel="stylesheet" />  <script src="/lib/jquery/dist/jquery.js"></script>  <script src="/lib/bootstrap/dist/js/bootstrap.js"></script>  <script src="/js/UploadJs.js"></script></head><body>  <p class="row" style="margin-top:20%">    <p class="col-lg-4"></p>    <p 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>    </p>    <p class="col-lg-4"></p>  </p></body></html>

2).javascript:

var UploadPath = "";//開始上傳function UploadStart() {  var file = $("#path")[0].files[0];  AjaxFile(file, 0);}function AjaxFile(file, i) {  var name = file.name, //檔案名稱  size = file.size, //總大小shardSize = 2 * 1024 * 1024,   shardSize = 2 * 1024 * 1024,//以2MB為一個分區  shardCount = Math.ceil(size / shardSize); //總片數  if (i >= shardCount) {    return;  }  //計算每一片的起始與結束位置  var start = i * shardSize,  end = Math.min(size, start + shardSize);  //構造一個表單,FormData是HTML5新增的  var form = new FormData();  form.append("data", file.slice(start, end)); //slice方法用於切出檔案的一部分  form.append("lastModified", file.lastModified);  form.append("fileName", name);  form.append("total", shardCount); //總片數  form.append("index", i + 1); //當前是第幾片  UploadPath = file.lastModified  //Ajax提交檔案  $.ajax({    url: "/Upload/UploadFile",    type: "POST",    data: form,    async: true, //非同步    processData: false, //很重要,告訴jquery不要對form進行處理    contentType: false, //很重要,指定為false才能形成正確的Content-Type    success: function (result) {      if (result != null) {        i = 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!!!");        }      }    }  });}

這裡的主要思路是利用html5 File api的slice方法把檔案分塊,然後new一個FormData()對象用於儲存檔案資料,之後就是遞迴調用AjaxFile方法直至上傳完畢。

2.後台C#:

using System;using System.Collections.Generic;using System.Linq;using System.Threading.Tasks;using Microsoft.AspNetCore.Mvc;using System.IO;// For more information on enabling MVC for empty projects, visit http://www.php.cn/namespace DotNet.Upload.Controllers{  public class UploadController : Controller  {    // GET: /<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(@"E:\瀏覽器", 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);          });        }        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);//刪除檔案夾        throw ex;      }    }    public async Task<bool> FileMerge(string lastModified,string fileName)    {      bool ok = false;      try      {        var temporary = Path.Combine(@"E:\瀏覽器", lastModified);//臨時檔案夾        fileName = Request.Form["fileName"];//檔案名稱        string fileExt = Path.GetExtension(fileName);//擷取檔案尾碼        var files = Directory.GetFiles(temporary);//獲得下面的所有檔案        var finalPath = Path.Combine(@"E:\瀏覽器", DateTime.Now.ToString("yyMMddHHmmss") + fileExt);//最終的檔案名稱(demo中儲存的是它上傳時候的檔案名稱,實際操作肯定不能這樣)        var fs = new FileStream(finalPath, FileMode.Create);        foreach (var part in files.OrderBy(x => x.Length).ThenBy(x => x))//排一下序,保證從0-N Write        {          var bytes = System.IO.File.ReadAllBytes(part);          await fs.WriteAsync(bytes, 0, bytes.Length);          bytes = null;          System.IO.File.Delete(part);//刪除分塊        }        fs.Close();        Directory.Delete(temporary);//刪除檔案夾        ok = true;      }      catch (Exception ex)      {        throw ex;      }      return ok;    }  }}

這裡的思路就是先儲存每一個分塊的檔案到一個臨時檔案夾,最後再通過FileStream合并這些臨時檔案(合并時必需要按順序)。背景方法都進行了非同步化(async await真的非常好用),雖然不知道對效率有沒有提升,但是就是覺得這樣很酷。

源碼下載:DotNet_jb51.rar

以上就是本文的全部內容,希望對大家的學習有所協助,也希望大家多多支援topic.alibabacloud.com。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.