带进度条的分片上传大文件
0.思路
通过JavaScript把文件分隔成小块,循环上传到后台。
1.HTML表单
<form id="form1" name="form1" method="post" enctype="multipart/form-data">
<input type="file" name="file2" id="file2" />
<input type="button" onclick="doUpload()" value="提交" />
</form>
<div class="progressWarp">
<div id="progress">
</div>
</div>
2.JavaScript
<script type="text/javascript">
function doUpload(){
var file = $("#file2")[0].files[0];
var index = 0;
uploadFile(file, index);
}
function uploadFile(file, index) {
var name = file.name,
size = file.size;
var shardSize = 2 * 1024 * 1024;
var shardCount = Math.ceil(size / shardSize);
if (index == shardCount)
return;
var start = index * shardSize,
end = Math.min(size, start + shardSize);
var data = file.slice(start, end);
var form = new FormData();
form.append("data", data);
form.append("filetextname", name);
form.append("total", shardCount);
form.append("index", index + 1);
form.append("size", size);
data = null;
$.ajax({
url: "<%=request.getContextPath()%>/PartUpload",
type : "POST",
data : form,
async : true,
processData : false,
contentType : false,
cache : false
}).done(function(data){
setProgress(index,shardCount);
index++;
form = null;
uploadFile(file, index);
}).fail(function(xhr, errmsg, errobject){
alert(errmsg);
}).always(function(xhr, status){
});
}
function setProgress(index, shardCount) {
var succeed = index + 1;
var per = (succeed / shardCount).toFixed(2) * 100;
$("#progress").html(per.toFixed(0) + "%");
if (per >= 100) {
per = 100;
$("#progress").html(per + "%");
}
$("#progress").attr("style", "width: " + per + "%;");
}
</script>
3.Java实现代码
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.lang3.StringUtils;
@WebServlet("/PartUpload")
public class PartUpload extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String attachPath = "D:/diaotest/";
Map<String, Object> map = getParameter(request);
Integer index =Integer.valueOf(map.get("index").toString());
String fileName = map.get("filetextname").toString();
Object attachObject = map.get("data");
if (attachObject != null && String.valueOf(attachObject).length() > 0) {
Map<String, String> map2 = upLoadFile((FileItem) attachObject, attachPath,fileName);
}
response.getOutputStream().write("success".getBytes());
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
public Map<String, String> upLoadFile(FileItem fileItem, String path,String fileName) {
if (fileItem == null)
return null;
Map<String, String> map = new HashMap<>();
File file = new File(path, fileName);
InputStream is = null;
OutputStream os = null;
try {
is = new BufferedInputStream(fileItem.getInputStream());
os = new BufferedOutputStream(new FileOutputStream(file, true));
int len = 0;
byte[] bs = new byte[8192];
while ((len = is.read(bs)) != -1) {
os.write(bs, 0, len);
}
os.flush();
is.close();
os.close();
fileItem.delete();
map.put(fileName, fileItem.getName());
return map;
} catch (IOException e) {
e.printStackTrace();
return map;
} finally {
try {
is.close();
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static Map<String, Object> getParameter(HttpServletRequest request) {
Map<String, Object> map = new HashMap<>();
String contentType = request.getContentType();
if (StringUtils.isEmpty(contentType)) {
return null;
}
if (contentType.indexOf("multipart/form-data") == -1) {
return getDataParameter(request);
} else {
DiskFileItemFactory factory = new DiskFileItemFactory();
factory.setSizeThreshold(3 * 1024 * 1024);
ServletFileUpload fileUpload = new ServletFileUpload(factory);
fileUpload.setHeaderEncoding("UTF-8");
try {
List<FileItem> list = fileUpload.parseRequest(request);
for (FileItem fileItem : list) {
if (fileItem.isFormField()) {
String name = fileItem.getFieldName();
String value = fileItem.getString("UTF-8");
map.put(name, value);
} else {
String fieldName = fileItem.getFieldName();
map.put(fieldName, fileItem);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
return map;
}
public static Map<String, Object> getDataParameter(HttpServletRequest request) {
Map<String, Object> map = new HashMap<>();
Enumeration<String> names = request.getParameterNames();
while (names.hasMoreElements()) {
String value = "";
String strings = (String) names.nextElement();
String[] parameterValues = request.getParameterValues(strings);
for (int i = 0; parameterValues != null && i < parameterValues.length; i++) {
if (i > 0) {
value += ";";
}
value += parameterValues[i];
}
map.put(strings, value);
}
return map;
}
}
4.NET后台实现
/// <summary>
/// 分块上传
/// </summary>
/// <returns></returns>
[HttpPost]
public ActionResult AjaxUpLoadFull()
{
string message = string.Empty;
string docId = Request["docid"];
string fullFileName = docId;
string name = Request["name"];
int total = Request["total"].ToInteger();
int index = Request["index"].ToInteger();
int size = Request["size"].ToInteger();
var data = Request.Files["data"];
//扩展名
string fileExt = Path.GetExtension(name);
fullFileName = fullFileName + fileExt;
if (index == 1)
{
//直接更新数据库吧
}
string dir = "D:/test";
string file = Path.Combine(dir, fullFileName);
FileStream fs = new FileStream(file, FileMode.Append);
byte[] buffer = new byte[data.ContentLength];
data.InputStream.Read(buffer, 0, data.ContentLength);
fs.Write(buffer, 0, data.ContentLength);
fs.Flush();
fs.Close();
return Json(message);
}