> 백엔드 개발 > C#.Net 튜토리얼 > asp.net 코어에서 파일을 청크로 업로드하는 예

asp.net 코어에서 파일을 청크로 업로드하는 예

高洛峰
풀어 주다: 2017-02-20 17:16:35
원래의
1567명이 탐색했습니다.

asp.net 다중 파일 업로드를 작성하고 나서 이런 종류의 업로드에는 아직 결함이 많다고 느꼈기 때문에. . . (10,000단어 생략, 말도 안되는 내용은 생략) 여기서는 전통적인 asp.net을 사용하지 않고 오픈소스 asp.net 코어를 선택한 이유는 매우 간단합니다. .net 코어는 .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 + &#39;%&#39;);
        AjaxFile(file, i);
        if (result.mergeOk) {
          var filepath = $("#path");
          filepath.after(filepath.clone().val(""));
          filepath.remove();//清空input file
          $(&#39;#upfile&#39;).val(&#39;请选择文件&#39;);
          alert("success!!!");
        }
      }
    }
  });
}
로그인 후 복사

여기서 주요 아이디어는 html5 File API의 슬라이스 방법을 사용하여 파일을 덩어리로 나누는 것입니다. 그런 다음 새로운 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 //m.sbmmt.com/

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 wait는 사용하기 매우 쉽습니다). 효율성이 향상되는지는 모르겠지만 멋지다고 생각합니다.

소스코드 다운로드: DotNet_jb51.rar

위 내용은 모두의 학습에 도움이 되기를 바라며, 또한 많은 지원 바랍니다. PHP 중국어 웹사이트.

asp.net 코어 청크 파일 업로드 예제 관련 기사를 더 보려면 PHP 중국어 웹사이트를 주목하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿