参考:
https://blog.csdn.net/susuzhe123/article/details/73743509
https://www.cnblogs.com/baiyunchen/p/5383507.html
直接上代码:
前台:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title></title>
<script src="../Scripts/jquery-1.8.2.js"></script>
</head>
<body>
<input type="file" id="file" />
<button id="upload">上传</button>
<span id="output">等待中</span>
</body>
<script>
var page = {
init: function () {
$("#upload").click($.proxy(this.upload, this));
},
upload: function () {
var file = $("#file")[0].files[0], //文件对象
name = file.name, //文件名
size = file.size, //总大小
succeed = 0;
var shardSize = 4 * 1024 * 1024, //以4MB为一个分片
shardCount = Math.ceil(size / shardSize); //总片数
for (var i = 0; i < shardCount; ++i) {
//计算每一片的起始与结束位置
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("name", name);
form.append("total", shardCount); //总片数
form.append("index", i + 1); //当前是第几片
//Ajax提交
$.ajax({
url: "../Test/Upload",
type: "POST",
data: form,
async: true, //异步
processData: false, //jquery不要对form进行处理
contentType: false, //指定为false才能形成正确的Content-Type
success: function () {
//成功后的事件
succeed++;
if (succeed == shardCount)
{
Merge();
}
}
});
}
}
};
function Merge() {
$.ajax({
url: "../Test/Merge",
type: "get",
success: function () {
}
});
}
$(function () {
page.init(); //初始化
});
</script>
</html>
后台:
[HttpPost]
public ActionResult Upload()
{
string fileName = Request["name"];
int index = Convert.ToInt32(Request["index"]);//当前分块序号
var folder = "myTest";
var dir = Server.MapPath("~/Images");//文件上传目录
dir = Path.Combine(dir, folder);//临时保存分块的目录
if (!System.IO.Directory.Exists(dir))
System.IO.Directory.CreateDirectory(dir);
string filePath = Path.Combine(dir, index.ToString());
var data = Request.Files["data"];//表单中取得分块文件
data.SaveAs(filePath);//保存
return Json(new { erron = 0 });
}
public ActionResult Merge()
{
var folder = "myTest";
var uploadDir = Server.MapPath("~/Images");//Upload 文件夹
var dir = Path.Combine(uploadDir, folder);//临时文件夹
var fileName = "MyTest.jpg";//文件名
var files = System.IO.Directory.GetFiles(dir);//获得下面的所有文件
var finalPath = Path.Combine(uploadDir, fileName);//最终的文件名(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);
fs.Write(bytes, 0, bytes.Length);
bytes = null;
System.IO.File.Delete(part);//删除分块
}
fs.Close();
System.IO.Directory.Delete(dir);//删除文件夹
return Json(new { error = 0 });//随便返回个值,实际中根据需要返回
}
解释一下:
首先,前台ajax调用upload方法,分块上传了文件
然后,上传完毕后前台调用 Merge方法合并文件