1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
|
<%@ Page Language=
"C#"
Inherits=
"System.Web.Mvc.ViewPage<dynamic>"
%>
<!DOCTYPE html>
<html lang=
"zh-CN"
>
<head>
<meta charset=
"utf-8"
>
<title>HTML5大文件分片上传示例</title>
<script src=
"../Scripts/jquery-1.11.1.min.js"
></script>
<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 = 2 * 1024 * 1024,
//以2MB为一个分片
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:
"../File/Upload"
,
type:
"POST"
,
data: form,
async:
true
,
//异步
processData:
false
,
//很重要,告诉jquery不要对form进行处理
contentType:
false
,
//很重要,指定为false才能形成正确的Content-Type
success:
function
(){
++succeed;
$(
"#output"
).text(succeed +
" / "
+ shardCount);
}
});
}
}
};
$(
function
(){
page.init();
});
</script>
</head>
<body>
<input type=
"file"
id=
"file"
/>
<button id=
"upload"
>上传</button>
<span id=
"output"
style=
"font-size:12px"
>等待</span>
</body>
</html>
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
[HttpPost]
public
ActionResult Upload()
{
//从Request中取参数,注意上传的文件在Requst.Files中
string
name = Request[
"name"
];
int
total = Convert.ToInt32(Request[
"total"
]);
int
index = Convert.ToInt32(Request[
"index"
]);
var
data = Request.Files[
"data"
];
//保存一个分片到磁盘上
string
dir = Server.MapPath(
"~/Upload"
);
string
file = Path.Combine(dir, name +
"_"
+ index);
data.SaveAs(file);
//如果已经是最后一个分片,组合
//当然你也可以用其它方法比如接收每个分片时直接写到最终文件的相应位置上,但要控制好并发防止文件锁冲突
if
(index == total)
{
file = Path.Combine(dir, name);
var
fs =
new
FileStream(file, FileMode.Create);
for
(
int
i = 1;i <= total;++i)
{
string
part = Path.Combine(dir, name +
"_"
+ i);
var
bytes = System.IO.File.ReadAllBytes(part);
fs.Write(bytes, 0, bytes.Length);
bytes =
null
;
System.IO.File.Delete(part);
}
fs.Close();
}
//返回是否成功,此处做了简化处理
return
Json(
new
{ Error = 0 });
}
|