.NetCore+WebUploader实现大文件分片上传
项目要求通过网站上传大文件,比如视频文件,通过摸索实现了文件分片来上传,然后后台进行合并。
使用了开源的前台上传插件WebUploader(http://fex.baidu.com/webuploader/)
WebUploader是由Baidu WebFE(FEX)团队开发的一个简单的以HTML5为主,FLASH为辅的现代文件上传组件。在现代的浏览器里面能充分发挥HTML5的优势,同时又不摒弃主流IE浏览器,沿用原来的FLASH运行时,兼容IE6+,iOS 6+, android 4+。两套运行时,同样的调用方式,可供用户任意选用。
采用大文件分片并发上传,极大的提高了文件上传效率。
最新升级版请访问:
直接上代码,前台cshtml
@{
Layout = null;
}
Upload
只能上传mpg、mpeg、mp4、avi格式的视频文件
选择文件
后台代码:
#region 上传视频
public IActionResult Upload()
{
ViewBag.Token = HttpContext.Request.Headers["Authorization"];//获取认证信息,传递给前台,方便Ajax请求时提供
return View();
}
///
/// 上传文件
///
///
[HttpPost]
public async Task FileSave()
{
var date = Request;
var files = Request.Form.Files;
long size = files.Sum(f => f.Length);
foreach (var formFile in files)
{
if (formFile.Length > 0)
{
string fileExt = formFile.FileName.Substring(formFile.FileName.IndexOf('.')); //文件扩展名,不含“.”
long fileSize = formFile.Length; //获得文件大小,以字节为单位
//string newFileName = Guid.NewGuid().ToString() + "." + fileExt; //随机生成新的文件名
string DirPath = Path.Combine(_uploadConfig.TmpPath, Request.Form["guid"]);
if (!Directory.Exists(DirPath))
{
Directory.CreateDirectory(DirPath);
}
var filePath = DirPath + "/" + Request.Form["chunk"] + fileExt;
using (var stream = new FileStream(filePath, FileMode.Create))
{
await formFile.CopyToAsync(stream);
}
}
}
return Ok(new { count = files.Count, size });
}
///
/// 合并请求
///
///
[HttpPost]
public async Task FileMerge()
{
bool ok = false;
string errmsg = "";
try
{
var temporary = Path.Combine(_uploadConfig.TmpPath, Request.Form["guid"]);//临时文件夹
string fileName = Request.Form["fileName"];//文件名
string fileExt = Path.GetExtension(fileName);//获取文件后缀
var files = Directory.GetFiles(temporary);//获得下面的所有文件
var finalFilePath = Path.Combine(_uploadConfig.UpLoadPath + fileName);//最终的文件名
//var fs = new FileStream(finalFilePath, FileMode.Create);
using (var fs = new FileStream(finalFilePath, FileMode.Create))
{
foreach (var part in files.OrderBy(x => x.Length).ThenBy(x => x))
{
var bytes = System.IO.File.ReadAllBytes(part);
await fs.WriteAsync(bytes, 0, bytes.Length);
bytes = null;
System.IO.File.Delete(part);//删除分块
}
Directory.Delete(temporary);//删除文件夹
ok = true;
}
}
catch (Exception ex)
{
ok = false;
errmsg = ex.Message;
log4net.Error(errmsg);
}
if (ok)
{
return Ok(new { success = true, msg = "" });
}
else
{
return Ok(new { success = false, msg = errmsg }); ;
}
}
#endregion