asp.net core 上传大文件
起因
最近遇到一个上传视频大文件的需求,文件最少是1个G的视频文件.一直以来没做过这么大的上传文件的功能.原先都是限制上传大小.在有HTML5了以后,可以对文件进行分割上传.这里是用plupload + Asp.Net Core来实现,其实是新瓶装老酒.
遇到的问题:
1. 怎么给上传文件重命名呢? 是在前台处理呢? 还是后台处理呢?
前台页面代码
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>Index</title>
</head>
<body>
<div id="uploadContainer">
<input type="button" value="选择文件" id="btnBrowse" />
<input type="button" value="上传文件" id="btnUpload" />
<ul id="fileList"></ul>
</div>
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/js/plupload/plupload.full.min.js"></script>
<script type="text/javascript">
var $uploadContainer = $('#uploadContainer'),
$fileList = $('#fileList'),
$btnUpload = $('#btnUpload');
//实例化一个上传对象
var uploader = new plupload.Uploader({
browse_button: 'btnBrowse',
runtimes: 'html5,flash,silverlight,html4', //兼容的上传方式
url: '/UploadFile/UploadVideo', //上传文件的地址
flash_swf_url: 'plupload/Moxie.swf',
sliverlight_xap_url: 'plupload/Moxie.xap',
max_retries: 3, //允许重试次数
chunk_size: '10mb', //分块大小
multi_selection: false, //只能选择单个文件进行上传
multipart_params: {
uploadFileName: '' //大文件分块之后,要在接收action中修改文件名的话,会生成多个文件
},
filters: {
mime_types: [
{
title: "视频文件",
extensions: "wmv,avi,mp4", //只允许上传文件格式
max_file_size: '4096mb' //允许上传文件的最大为4g
}
]
}
});
//存储多个图片的url地址
var urls = [];
//存储触犯上传事件的事件对象
var event;
//初始化
uploader.init();
//绑定文件添加到队列的事件
uploader.bind('FilesAdded', function (uploader, files) {
var value = files[0];
var fileName = value.name,
html = '<li id="file-' + value.id + '">' +
'<p class="file-name">' + fileName + '</p>' +
'<p class="progress"></p>' +
'</li>';
$fileList.html(html);
});
//绑定上传进度
uploader.bind('UploadProgress', function (uploader, file) {
$fileList.find('.progress').text(file.percent + '%');
});
//单个文件上传之后
uploader.bind('FileUploaded', function (uploader, file, responseObject) {
//从服务器返回图片url地址
var url = responseObject.response;
//先将url地址存储来,
urls.push(url);
});
//文件完成上传事件
uploader.bind('UploadComplete', function (uploader, files) {
var value = urls[0]; //取第1个元素
var result = JSON.parse(value); //转为json之后,判断是否全部上传完成
if (result.isSuccess) {
$.ajax({
type: 'POST',
dataType: 'json',
url: '/UploadFile/SaveVideoURL',
data: {
'videoURL': result.videoURL
},
success: function (data) {
if (data.isSuccess) {
alert('上传文件成功!');
}
else {
alert('上传文件失败!');
}
}
});
}
//清空url数组
urls = [];
//清空显示列表
$fileList.html('');
});
//上传事件
$btnUpload.click(function (e) {
event = e;
uploader.setOption('multipart_params', {
'uploadFileName': new Date().getTime() //上传的时候,根据时间的毫秒数当作保存的文件名
});
uploader.start();
});
function getFileName() {
return new Date().getTime();
}
</script>
</body>
</html>
后台代码
using System.IO;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
namespace qiufeng.core.Controllers
{
public class UploadFileController : Controller
{
private IHostingEnvironment _hostEnv;
public UploadFileController(IHostingEnvironment env)
{
_hostEnv = env;
}
/// <summary>
/// 上传文件
/// </summary>
/// <returns></returns>
public IActionResult Index()
{
return View();
}
/// <summary>
/// 处理上传文件
/// </summary>
/// <returns></returns>
[HttpPost]
public IActionResult UploadVideo()
{
var files = Request.Form.Files;
if (files != null)
{
string uploadFileName = Request.Form["uploadFileName"]; //获取要保存的文件名
string fileName = Request.Form["name"]; //上传的文件名
string extName = Path.GetExtension(fileName); //获取文件的扩展名
fileName = $"{uploadFileName}{extName}"; //合并要保存的文件名
string filePath = Path.Combine(_hostEnv.ContentRootPath, "UploadFile", fileName); //要保存的路径
string videoURL = $"/UploadFile/{fileName}";
//分块,第一次为0,根据这个标记不为0,开始对文件追加
int chunk = string.IsNullOrEmpty(Request.Form["chunk"]) ? 0 : int.Parse(Request.Form["chunk"]);
foreach (var file in files)
{
using (var stream = new FileStream(filePath, chunk == 0 ? FileMode.CreateNew : FileMode.Append))
{
file.CopyTo(stream);
}
}
return Json(new { isSuccess = true, videoURL = videoURL });
}
return Json(new { isSuccess = false, videoURL = "" });
}
/// <summary>
/// 在大文件上传完成之后,关联保存的信息
/// </summary>
/// <returns></returns>
[HttpPost]
public IActionResult SaveVideoURL()
{
bool isSuccess = false;
string videoURL = Request.Form["videoURL"];
if (!string.IsNullOrEmpty(videoURL))
{
//对应关联有关联的id,这里只是模拟,要将videoURL保存起来
isSuccess = true;
}
return Json(new { isSuccess = isSuccess });
}
}
}
秋风
2017-07-07