首先是前台代码:
1、html文件
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>文件上传</title>
<script type="text/javascript" src="/js/jquery.js"></script>
<script type="text/javascript" src="/js/spark-md5.js"></script>
<script type="text/javascript" src="/js/myUpload.js"></script>
<link rel="stylesheet" href="/css/bootstrap.min.css" />
<style>
body{
padding:10px;
}
.upload,.progress{
display:inline-block;
vertical-align: middle;
margin:0;
}
</style>
</head>
<body>
<input id="isPause" value="1" style="display: none"/>
<input id="hashcode" value="" style="display: none"/>
<input id="temphashcode" value="" style="display: none"/>
<input id="tempFileName" value="" style="display: none"/>
<input id="fileName" value="" style="display: none"/>
<div id="cont">
<div class="upload">
<button type="button" id="upload" class="btn btn-primary">选择文件</button>
<button type="button" id="isPauseButton" class="btn btn-primary" >暂停</button>
<input id="myupload" type="file" style="display:none;" />
<div id="uploadProgress"></div>
</div>
</div>
</body>
</html>
2、css文件,使用bootstrap
3、js文件,使用spark-md5.js
/**
* Created by lxg on 2016/12/20.
*/
/**
* 文件对象
*/
var fileObj = {
upLoadSize : 0
};
/**
* 上传配置
*/
var opt = {
blodSize : 1024*1024*10, //文件分片大小
method : 'POST', //请求方式
fileObjName : 'file', //后台接收的文件名(后台使用spring mvc时此项不必要)
uploadUrl : 'http://localhost:8080/file/uploadFile', //文件上传地址
getUploadedSizeUrl : 'http://localhost:8080/file/uploadSize' ,//获取文件已上传大小地址
getUploadFileInfoUrl:'http://localhost:8080/file/getUploadFileInfo',
getRealFileNameUrl:'http://localhost:8080/file/getRealFileName',
delTempFileUrl:'http://localhost:8080/file/delTempFile',
hash:"",
};
/*监听文件是否改变*/
$(function () {
$("#myupload").change(function (e) {
opt.hash="";//重新计算哈希值
var file = e.target.files[0];
console.log(file.lastModifiedDate.getTime());
fileObj.name = file.name;
// $('#filename').val(file.name);
$('#tempFileName').val(file.name);
fileObj.size = file.size;//文件初始大小
fileObj.oldFile = file;
fileObj.upLoadSize = 0;
afterChange(file);
var flag = true;
var newName="";
var prefix = fileObj.name.substr(0,fileObj.name.lastIndexOf('.'));
var suffix = fileObj.name.substr(fileObj.name.lastIndexOf('.'));
var uploadFileInfo=null;
var i = 1;
while(flag){
uploadFileInfo = getUploadFileInfo(fileObj.oldFile);
if(uploadFileInfo==''){
flag = false;
}else{
$('#tempFileName').val(prefix+"-part"+ (i) +suffix);
fileObj.name= prefix+"-part"+ i++ +suffix;
}
}
var blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice,
file = this.files[0],
chunkSize = 1024*1024*100, // Read in chunks of 100MB
chunks = Math.ceil(file.size / chunkSize),
currentChunk = 0,
spark = new SparkMD5.ArrayBuffer(),
fileReader = new FileReader();
var sparkmd5 = spark.end();
fileReader.onload = function (e) {
// console.log('read chunk nr', currentChunk + 1, 'of', chunks);
spark.append(e.target.result); // Append array buffer
currentChunk++;
if (currentChunk < chunks) {
loadNext();
} else {
var arrN = utf8Str2ArrayBuffer(file.name,true);
var arrU = utf8Str2ArrayBuffer(file.lastModifiedDate.getTime()+"",true);
spark.append(arrN);
spark.append(arrU);
var localhash = spark.end();
console.log('finished loading');
console.log(localhash);
$('#temphashcode').val(localhash);
var realFilename;
//获取哈希相同的文件名
$.ajax({
url : opt.getRealFileNameUrl,
data : {'name':fileObj.name,"hash":localhash},
async:false,
type : 'POST',
success : function(returnData){
realFilename = returnData.fileName;
$('#fileName').val(returnData.tempFileName);
}
});
/*if(localhash==servhash){
deleteTempFile(file);
$('#tempFileName').val($('#filename'));
fileObj.upLoadSize=getUpLoadSize(file);
}*/
if(realFilename!=null && realFilename!=''){
$('#tempFileName').val(realFilename);
fileObj.upLoadSize=getUpLoadSize(file);
}
}
};
fileReader.onerror = function () {
console.warn('oops, something went wrong.');
};
function loadNext() {
var start = currentChunk * chunkSize,
end = ((start + chunkSize) >= file.size) ? file.size : start + 1024*1024;
fileReader.readAsArrayBuffer(blobSlice.call(file, start, end));
}
loadNext();
});
//监听选择文件按钮
$("#upload").click(function (e) {
$("#myupload").click()
});
//监听暂停按钮
$("#isPauseButton").click(function (e) {
var v1 = Number($("#isPause").val());
if(v1==1){
$("#isPause").val(0);
$("#isPauseButton").text("继续")
}else{
$("#isPause").val(1);
$("#isPauseButton").text("暂停")
var blob = getBlod(fileObj.oldFile);
sendBlob(opt.uploadUrl,blob,{'name':fileObj.name});
}
});
//选择文件之后
var afterChange = function(file){
var str = '<div class="progress" style="width:400px;">'
+'<div id="progress" class="progress-bar progress-bar-success progress-bar-striped" role="progressbar" '
+'aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" style="width:0%;">'
+'</div></div>'
+' <span id="filename">'+fileObj.name+'</span> <button class="btn btn-primary fileupload">上传</button> ';
$("#uploadProgress").html(str);
$('.fileupload').on('click',(function(){
return function(){upload(file);}
})(file));
}
//点击上传按钮事件后响应函数
var upload = function(file){
console.log(fileObj.name);
var blob = getBlod(fileObj.oldFile);
sendBlob(opt.uploadUrl,blob,{'name':fileObj.name});
}
/**
* 分割文件
* @param file
* @returns {string|Blob|Array.<T>|ArrayBuffer|*}
*/
var getBlod = function (file) {
var upLoadSize = 0;
if(!fileObj.upLoadSize > 0){
upLoadSize = getUpLoadSize(file);
}else{
upLoadSize = fileObj.upLoadSize;
}
var end = Number(upLoadSize)+Number(opt.blodSize);
var BoldFile = file.slice(upLoadSize,end);
return BoldFile;
}
/**
* 获取已上传文件大小
* @param file
* @returns {number}
*/
var getUpLoadSize = function (file) {
var uploadedSize = 0;
$.ajax({
url : opt.getUploadedSizeUrl,
data : {'name':fileObj.name,'size':fileObj.size,"fileSize":fileObj.size,"hash":$("#temphashcode").val()},
async:false,
type : 'POST',
success : function(returnData){
uploadedSize = returnData.size;
$('#hashcode').val(returnData.hashcode);
}
});
return uploadedSize;
}
var getUploadFileInfo = function (file) {
var uploadFileInfo;
$.ajax({
url:opt.getUploadFileInfoUrl,
data : {'name':fileObj.name},
async:false,
type : 'POST',
success : function(returnData){
uploadFileInfo = returnData;
}
});
return uploadFileInfo;
}
/**
* 上传文件块
* @param url
* @param file
* @param formdata
*/
var sendBlob = function(url,file,formdata){
fileObj.name = $('#tempFileName').val();
var v1 = Number($("#isPause").val());
var xhr=new XMLHttpRequest();
xhr.open(opt.method, url, true);
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
var fd = new FormData();
fd.append(opt.fileObjName,file);
fd.append('fileNameT',fileObj.name);
console.log(file);
// fd.apend("fileTemp",file.name)
if(formdata){
for(key in formdata){
fd.append(key,formdata[key]);
}
}
xhr.send(fd);
xhr.onreadystatechange = function(e) {
if (xhr.readyState == 4) {
fileObj.uploadOver = true;
if (xhr.status == 200) {
//console.log("over")
fileObj.upLoadSize = getUpLoadSize(file);
onProgress(file, fileObj.upLoadSize, fileObj.size);
if(fileObj.upLoadSize < fileObj.size && v1==1){
//console.log(fileObj.upLoadSize)
sendBlob(opt.uploadUrl,getBlod(fileObj.oldFile),{'name':fileObj.name});
}else{
$.ajax({
url:opt.delTempFileUrl,
data : {'name':$('#fileName').val()},
type:'POST',
success : function(returnData){
console.log("成功删除副本文件")
}
});
}
}
}
}
}
/**
* 进度条处理
* @param file
* @param loaded
* @param size
*/
var onProgress = function (file, loaded, size) {
console.log("本次已上传:"+loaded)
console.log("upLoadSize:"+fileObj.upLoadSize)
var p = (((parseInt(fileObj.upLoadSize))/parseInt(fileObj.size))*100).toFixed(2)
console.log(p)
$("#progress").css('width',p+'%');
var percentText = p > 100 ? '100.00%' : p +'%';
$("#bfb").html(percentText);
}
function utf8Str2ArrayBuffer(str, returnUInt8Array) {
var length = str.length,
buff = new ArrayBuffer(length),
arr = new Uint8Array(buff),
i;
for (i = 0; i < length; i += 1) {
arr[i] = str.charCodeAt(i);
}
return returnUInt8Array ? arr : buff;
}
});
4、后台代码
package com.zhang.controller;
import com.zhang.pojo.UploadFileInfo;
import com.alibaba.fastjson.JSON;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisShardInfo;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.RandomAccessFile;
import java.util.Iterator;
@Controller
@RequestMapping("/file")
public class FileController {
public static String PATH = "e:/testUpload";
@RequestMapping("index")
public String index(){
return "file/demo";
}
@RequestMapping(value = "getRealFileName",method = RequestMethod.POST)
@ResponseBody
public UploadFileInfo getRealFileName(HttpServletRequest request){
UploadFileInfo uploadFileInfo = new UploadFileInfo();
String name = request.getParameter("name");
uploadFileInfo.setFileName(name);
String hash = request.getParameter("hash");
String realFileName = name;
if(name.contains("-part")){
try {
JedisShardInfo jedisShardInfo = new JedisShardInfo("10.18.10.101");
Jedis jedis = new Jedis(jedisShardInfo);
int len = new Integer(name.substring(name.lastIndexOf("-part")+5,name.lastIndexOf("."))).intValue();
String oldFileName = name.substring(0,name.lastIndexOf("-part"))+name.substring(name.lastIndexOf("."));
String str = jedis.get(oldFileName);
if(StringUtils.isNotBlank(str)){
UploadFileInfo uploadFileInfot = JSON.parseObject(str,UploadFileInfo.class);
if(hash.equals(uploadFileInfot.getHashcode())){
uploadFileInfo = uploadFileInfot;
if(!uploadFileInfot.getFileName().equals(name)){
uploadFileInfo.setTempFileName(name);
}
}
for(int i=1;i<len-1;i++){
oldFileName = name.substring(0,name.lastIndexOf("-part"))+"-part"+i+name.substring(name.lastIndexOf("."));
str = jedis.get(oldFileName);
if (StringUtils.isNotBlank(str)){
uploadFileInfot = JSON.parseObject(str,UploadFileInfo.class);
if(hash.equals(uploadFileInfot.getHashcode())){
realFileName = uploadFileInfo.getFileName();
uploadFileInfo = uploadFileInfot;
if(!uploadFileInfot.getFileName().equals(name)){
uploadFileInfo.setTempFileName(name);
}
break;
}
}
}
}
jedis.close();
}catch (Exception e){
e.printStackTrace();
}
}
return uploadFileInfo;
}
@RequestMapping(value = "getUploadFileInfo", method = RequestMethod.POST)
@ResponseBody
public UploadFileInfo getUploadFileInfo(HttpServletRequest request){
UploadFileInfo uploadFileInfo = null;
String name = request.getParameter("name");
try {
JedisShardInfo jedisShardInfo = new JedisShardInfo("10.18.10.101");
Jedis jedis = new Jedis(jedisShardInfo);
String str = jedis.get(name);
if(!StringUtils.isEmpty(str)){
uploadFileInfo = JSON.parseObject(str,UploadFileInfo.class);
}
} catch (Exception e) {
e.printStackTrace();
}
return uploadFileInfo;
}
@RequestMapping(value = "/uploadSize",method = RequestMethod.POST)
@ResponseBody
public UploadFileInfo uploadSize(HttpServletRequest request){
String name = request.getParameter("name");
Long size = Long.parseLong(request.getParameter("size"));
String hash=request.getParameter("hash");
try {
JedisShardInfo jedisShardInfo = new JedisShardInfo("10.18.10.101");
Jedis jedis = new Jedis(jedisShardInfo);
String str = jedis.get(name);
UploadFileInfo uploadFileInfo = null;
//如果首次上传
if(StringUtils.isEmpty(str)){
uploadFileInfo = new UploadFileInfo();
uploadFileInfo.setHashcode(hash);
jedis.set(name, JSON.toJSONString(uploadFileInfo));
jedis.close();
return uploadFileInfo;
}
uploadFileInfo = JSON.parseObject(str,UploadFileInfo.class);
if(StringUtils.isEmpty(uploadFileInfo.getHashcode())){
uploadFileInfo.setHashcode(hash);
jedis.set(name,JSON.toJSONString(uploadFileInfo));
}
System.out.println(uploadFileInfo.getFileName()+":"+uploadFileInfo.getSize()+":"+uploadFileInfo.getHashcode());
jedis.close();
//全部上传成功
if (uploadFileInfo.getSize()!=null&&size <= uploadFileInfo.getSize()){
System.out.println("上传完成");
}
return uploadFileInfo;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
@RequestMapping(value = "/uploadFile",method = RequestMethod.POST)
@ResponseBody
public int upload(HttpServletRequest request, @RequestParam(value = "file",required = false) MultipartFile multipartFile){
MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
Iterator<String> t = multiRequest.getFileNames();
MultipartFile fileDetail = multiRequest.getFile(t.next());
String name = request.getParameter("name");
JedisShardInfo jedisShardInfo = new JedisShardInfo("10.18.10.101");;
Jedis jedis = new Jedis(jedisShardInfo);
String uploadF = jedis.get(name);
if(StringUtils.isNotBlank(uploadF)){
UploadFileInfo uploadFileInfo = JSON.parseObject(uploadF,UploadFileInfo.class);
uploadFileInfo.setFileName(name);
String hashcode = uploadFileInfo.getHashcode();
File file = new File(PATH);
if(!file.exists() && !file.isDirectory()){
boolean f = file.mkdir();
}
File testF = new File(PATH+"/"+name);
RandomAccessFile randomFile = null;
try {
randomFile = new RandomAccessFile(PATH+"/"+name,"rw");
randomFile.seek(randomFile.length());;
randomFile.write(fileDetail.getBytes());
uploadFileInfo.setLocalPath(PATH+"/"+name);
uploadFileInfo.setSize(randomFile.length());
randomFile.close();
} catch (Exception e) {
e.printStackTrace();
}
//将上传信息保存到redis
jedis.set(name,JSON.toJSONString(uploadFileInfo));
}
jedis.close();
return 0;
}
@RequestMapping(value = "delTempFile",method = RequestMethod.POST)
@ResponseBody
public int delTempFile(HttpServletRequest request){
String name = request.getParameter("name");
if(StringUtils.isNotBlank(name)){
JedisShardInfo jedisShardInfo = new JedisShardInfo("10.18.10.101");;
Jedis jedis = new Jedis(jedisShardInfo);
jedis.del(name);
jedis.close();
File file = new File(PATH+"/"+name);
if (file.exists()&&!file.isDirectory()){
file.delete();
}
}
return 0;
}
}
5、pojo对象类:
public class UploadFileInfo {
private String tempFileName;
private long id;
private String hashcode;
private String fileName;
public String getFileName() {
return fileName;
}
private String localPath;
private String fileSize;
private Long size;