JAVA springboot 大文件分断极速上传带上传进度条
项目部分架构为html+js+springboot+springMVC
因为没有考虑周到,前期开发有试用WEB文件简单上传,WEB文件多线程上传,sevlet文件分断上传+进度条等,虽都成功,但效果差强人意,直到遇见百度的webuploader,这里感谢百度的webuploader插件开源,虽然网上人员对它的吐槽也不少,哈哈。下面正式开始贴上代码
由于这个功能我觉得有必要分享给大家,因为这个功能是半年前写的,现在贴上,写的不好,希望大家少喷
这里主要注意的问题是,CSS或JS引入不生效的问题,可以将它们直接放在JS脚本或CSS脚 本前引入,或注意顺序问题。
这里感谢一个人提供的CSDN博客。这里深表感谢。我是把他的代码直接拿过来修改即用的。
https://www.cnblogs.com/hackxiyu/p/8203400.html
webuploader API查阅官网
http://fex.baidu.com/webuploader/doc/index.html
一,首先前端需引入 代码片
.
<!--引入CSS-->
<link rel="stylesheet" type="text/css" href="webuploader文件夹/webuploader.css">
<!--引入JS-->
<script type="text/javascript" src="webuploader文件夹/webuploader.js"></script>
下载下面这个uploader.swf,并将它放入你的项目内,我放在了lib文件夹里
二,HTML代码
//文件选择按钮
<div id="uploader1" class="wu-example">
<div class="btns">
<span id="picker1"></span><span id="showtotalnumspan1"
style="display: none">您已选择<span
id="showfiletotalnum1"></span>个文件</span>
<br>
</div>
</div>
//进度条面板
<div id="thelist" class="uploader-list" style="display:none;"></div>
//文件上传事件按锯或清除按钮
<button id="ctlBtn" class="btn btn-default">开始上传</button>
<button id="" class="btn btn-default" onclick="clearFileData()">全部清空</button>
三,JS部分(重点)
1.初始化Web Uploader
var $btn = $('#ctlBtn'); //此为文件上传按钮
var $thelist = $('#thelist'); //此为进度条
var chunkSize = 5 * 1024 * 1024; //此为文件流管道大小,即一次传输5MB字节,意思是分断大小
// HOOK 这个必须要再uploader实例化前面
WebUploader.Uploader.register({
'before-send-f ile': 'beforeSendFile',
'before-send': 'beforeSend'
}, {
beforeSendFile: function (file) {
console.log("beforeSendFile");
// Deferred对象在钩子回掉函数中经常要用到,用来处理需要等待的异步操作。
var task = new $.Deferred();
// 根据文件内容来查询MD5
uploader.md5File(file).progress(function (percentage) { // 及时显示进度
console.log('计算md5进度:', percentage);
getProgressBar(file, percentage, "MD5", "MD5");
}).then(function (val) { // 完成
console.log('md5 result:', val);
file.md5 = val;
// 模拟用户id
// file.uid = new Date().getTime() + "_" + Math.random() * 100;
file.uid = WebUploader.Base.guid();
// 进行md5判断
$.post("/fileupdown/checkFileMd5", {uid: file.uid, md5: file.md5},
function (data) {
console.log(data.status);
var status = data.status.value;
task.resolve();
if (status == 101) {
// 文件不存在,那就正常流程
} else if (status == 100) {
// 忽略上传过程,直接标识上传成功;
//uploader.skipFile(file);
//file.pass = true;
} else if (status == 102) {
// 部分已经上传到服务器了,但是差几个模块。
file.missChunks = data.data;
}
});
});
return $.when(task);
},
beforeSend: function (block) {
console.log("block")
var task = new $.Deferred();
var file = block.file;
var missChunks = file.missChunks;
var blockChunk = block.chunk;
console.log("当前分块:" + blockChunk);
console.log("missChunks:" + missChunks);
if (missChunks !== null && missChunks !== undefined && missChunks !== '') {
var flag = true;
for (var i = 0; i < missChunks.length; i++) {
if (blockChunk == missChunks[i]) {
console.log(file.name + ":" + blockChunk + ":还没上传,现在上传去吧。");
flag = false;
break;
}
}
if (flag) {
task.reject();
} else {
task.resolve();
}
} else {
task.resolve();
}
return $.when(task);
}
});
// 实例化
var uploader1 = WebUploader.create({
pick:
{
id: '#picker1',
label: '选择文件',
multiple: true,
// 不同功能的上传按钮初始化赋值
webkitdirectory: false
},
formData: {
uid: 0,
md5: '',
chunkSize: chunkSize
},
//dnd: '#dndArea',
//paste: '#uploader',
//fileVal: 'fileFolder',
swf: 'js/Uploader.swf',
chunked: true,
chunkSize: chunkSize, // 字节 1M分块
threads: 3,
server: '/fileupdown/uploadFile',
auto: false,
compress: false,//不压缩图片
accept:null,
// 禁掉全局的拖拽功能。这样不会出现图片拖进页面的时候,把图片打开。
disableGlobalDnd: true,
fileNumLimit: 1024,
fileSizeLimit: 1024 * 1024 * 1024, // 200 M
fileSingleSizeLimit: 1024 * 1024 * 1024 // 50 M
});
var arr = "";//随机码
var totalFileNum1 = 0;
var allurls1 = new Array();
var goOne = true;
// 当有文件被添加进队列的时候
uploader1.on('fileQueued', function (file) {
if (goOne) {
$("#uploader").hide();
goOne = false;
}
allurls1[totalFileNum1] = file.name;
totalFileNum1++;
console.log("fileQueued");
$thelist.append('<div id="' + file.id + '" class="item">' +
'<h6 class="info">' + file.name + '</h6>' +
'<p class="state">等待上传...</p>' +
'</div>');
$("#showfiletotalnum1").html(totalFileNum1);
$("#showtotalnumspan1").show();
});
//当某个文件的分块在发送前触发,主要用来询问是否要添加附带参数,大文件在开起分片上传的前提下此事件可能会触发多次。
uploader1.onUploadBeforeSend = function (obj, data) {
console.log("onUploadBeforeSend");
var file = obj.file;
data.md5 = file.md5 || '';
data.uid = file.uid;
data.webkitRelativePath = obj.file.source.source.webkitRelativePath ? obj.file.source.source.webkitRelativePath : '';
data.orderNo = $("#orderno").val().trim();
data.salor = $("#salorid").val();
data.projectName = $("#projectno").val().trim();
data.fileNames = allurls1;
data.name = file.name;
data.saveFolderName = $("#folderselect").val();
data.randomNum = arr;
};
// 上传中
uploader1.on('uploadProgress', function (file, percentage) {
getProgressBar(file, percentage, "FILE", "上传进度");
});
// 上传返回结果
uploader1.on('uploadSuccess', function (file) {
var text = '已上传';
if (file.pass) {
text = "文件妙传功能,文件已上传。"
}
$('#' + file.id).find('p.state').text(text);
});
uploader1.on('uploadError', function (file) {
$('#' + file.id).find('p.state').text('上传出错');
});
uploader1.on('uploadComplete', function (file) {
// 隐藏进度条
// fadeOutProgress(file, 'MD5');
$("#" + file.id).hide();
fadeOutProgress(file, 'FILE');
});
var flagg = true;
var flaggg = false;
function checkMessageBeforeUpload() {
window.parent.document.getElementById('coverbehidepage').style.display = "block";
var salorid = $("#salorid").val();
var orderno = $("#orderno").val().trim();
var projecto = $("#projectno").val().trim();
var filePathName = "";
var fileName = "";
var reg = new RegExp(/^[A-Z]{5}[0-9]{8}[A-Z]{2}[0-9]{2}$/g);
var filesaveselect = $('input[name="filesaveselect"]:checked').val();
var url = "";
var formData = new FormData();
formData.append('orderNo', $("#orderno").val());
formData.append('salor', $("#salorid").val());
// if (typeof (filesaveselect) == "undefined") {
// if (totalFileNum1 != 0) {
// $("#folderselect").val("");
// showfolderdiv();
// $("#listshow").removeAttr("checked");
// $("#foldershow").prop("checked", 'checked');
// $("#listdiv").attr("style", "display:none;")
// $("#folderdiv").attr("style", "display:block;")
// alert("您没有指定文件夹,系统将默认存放在以订单为名和目录下!");
// window.parent.document.getElementById('coverbehidepage').style.display="none";
// }
// } else {
// $("#folderselect").val(filesaveselect);
// if (reg.test(filesaveselect)) {
// $("#folderselect").val("");
// }
// }
if (salorid == "" || salorid == null) {
alert("请选择业务人员!");
window.parent.document.getElementById('coverbehidepage').style.display = "none";
flagg = false;
clearUploder()
return false;
}
if (orderno == "") {
flagg = false;
clearUploder()
alert("请填写订单编号!");
window.parent.document.getElementById('coverbehidepage').style.display = "none";
return false;
}
if (projecto == "") {
alert("请填写项目名称!");
window.parent.document.getElementById('coverbehidepage').style.display = "none";
flagg = false;
clearUploder()
return false;
}
$("#folderselect").val(filesaveselect);
if (totalFileNum != 0) {
for (var i = 0; i < allurls.length; i++) {
var index = allurls[i].lastIndexOf('/');
var centerurl = allurls[i].substr(0, index);
if (allurls[i].indexOf(",") == -1 && centerurl.indexOf(".") == -1) {
filePathName += allurls[i] + ",";
} else {
if (allurls[i].indexOf(",") != -1) {
alert("您选择的文件夹名含有,符号,如:" + allurls[i]);
window.parent.document.getElementById('coverbehidepage').style.display = "none";
flagg = false;
clearUploder()
return false;
} else if (centerurl.indexOf(".") != -1) {
alert("您选择的文件夹名含有.符号,如:" + allurls[i]);
window.parent.document.getElementById('coverbehidepage').style.display = "none";
flagg = false;
clearUploder()
return false;
}
}
}
url = "/fileupdown/checkmessagefolder";
formData.append('filePathName', filePathName);
} else if (totalFileNum1 != 0) {
for (var i = 0; i < allurls1.length; i++) {
if (allurls1[i].indexOf(".") != -1) {
fileName += allurls1[i] + ",";
} else {
alert("文件名必须要有扩展名,如:" + allurls1[i] + "就没有扩展名!");
window.parent.document.getElementById('coverbehidepage').style.display = "none";
flagg = false;
clearUploder()
return false;
}
if (allurls1[i].indexOf(",") != -1) {
alert("文件名不能有,符号,如:" + allurls1[i]);
window.parent.document.getElementById('coverbehidepage').style.display = "none";
flagg = false;
clearUploder()
return false;
}
}
url = "/fileupdown/checkmessage";
formData.append('filePathName', fileName);
} else {
alert("上传前请选择文件!")
window.parent.document.getElementById('coverbehidepage').style.display = "none";
flagg = false;
clearUploder()
return false;
}
if (flagg) {
window.parent.document.getElementById('coverbehidepage').style.display = "block";
//第一步,checkmessage
$.ajax({
data: formData,
type: "POST",
url: url,
async: true,
cache: false,
contentType: false,
processData: false,
success: function (msg) {
window.parent.document.getElementById('coverbehidepage').style.display = "none";
if (msg != '"OK"') {
alert(msg);
flaggg = false;
clearUploder()
return flaggg;
} else {
flaggg = true;
return flaggg;
}
},
error: function (msg) {
window.parent.document.getElementById('coverbehidepage').style.display = "none";
alert("查询失败");
flaggg = false;
clearUploder()
return flaggg;
}
});
}
window.parent.document.getElementById('coverbehidepage').style.display = "none";
}
//url = "/fileupdown/checkmessage";
function saveData() {
var formData = new FormData();
formData.append('filePathName', $("#filePathName").val());
formData.append('orderNo', $("#orderno").val());
formData.append('salor', $("#salorid").val());
formData.append('projectName', $("#projectno").val().trim());
formData.append('random8', arr);
formData.append('filedescribtion', $("#filedescribtion").val());
formData.append('remark', $("#remark").val());
formData.append('saveFolderName', $("#folderselect").val());
if (totalFileNum != 0) {
formData.append('filePathNames', allurls);
$.ajax({
data: formData,
type: "POST",
url: "/fileupdown/saveFolderMessage",
async: true,
cache: false,
contentType: false,
processData: false,
success: function (msg) {
},
error: function (msg) {
alert("插入数据失败")
alert(msg)
console.log(msg)
}
});
} else if (totalFileNum1 != 0) {
formData.append('filePathNames', allurls1);
$.ajax({
data: formData,
type: "POST",
url: "/fileupdown/saveFileMessage",
async: true,
cache: false,
contentType: false,
processData: false,
success: function (msg) {
},
error: function (msg) {
}
});
}
}
//文件加进去时校验
uploader1.on('filesQueued', function (file) {
checkMessageBeforeUpload();
test();
});
uploader1.on('uploadFinished', function (file) {
saveData();
$("#coverbehidepage1").hide();
window.parent.document.getElementById('coverbehidepageLeft').style.display = "none";
window.parent.document.getElementById('coverbehidepageTop').style.display = "none";
window.parent.document.getElementById('coverbehidepage').style.display = "none";
$("#thelist").hide();
clearFileData();
alert("上传成功!")
});
$btn.on('click', function () {
var salorid = $("#salorid").val();
var orderno = $("#orderno").val().trim();
var projecto = $("#projectno").val().trim();
var reg = new RegExp(/^[A-Z]{5}[0-9]{8}[A-Z]{2}[0-9]{2}$/g);
var filesaveselect = $('input[name="filesaveselect"]:checked').val();
if (typeof (filesaveselect) == "undefined") {
if (totalFileNum1 != 0) {
$("#folderselect").val("");
$("#listshow").removeAttr("checked");
$("#foldershow").prop("checked", 'checked');
$("#listdiv").attr("style", "display:none;")
$("#folderdiv").attr("style", "display:block;")
alert("您没有指定文件夹,系统将默认存放在以订单为名和目录下!");
}
} else {
$("#folderselect").val(filesaveselect);
if (reg.test(filesaveselect)) {
$("#folderselect").val("");
}
}
if (salorid == "" || salorid == null) {
alert("请选择业务人员!");
flagg = false;
clearFileData()
return false;
}
if (orderno == "") {
flagg = false;
clearFileData()
alert("请填写订单编号!");
return false;
}
if (projecto == "") {
alert("请填写项目名称!");
flagg = false;
clearFileData()
return false;
}
if (totalFileNum1 == 0 && totalFileNum == 0) {
alert("上传前请选择需要上传的文件或文件夹!");
return false;
}
$("#folderselect").val(filesaveselect);
if (flaggg) {
$("#coverbehidepage1").show();//遮罩层开启
window.parent.document.getElementById('coverbehidepageLeft').style.display = "block";
window.parent.document.getElementById('coverbehidepageTop').style.display = "block";
$("#thelist").show();
//第二步,saveMessageandFileStore
if (totalFileNum1 != 0) {
uploader1.upload();
} else if (totalFileNum != 0) {
uploader.upload();
} else if (totalFileNum1 == 0 && totalFileNum == 0) {
alert("上传前请选择需要上传的文件或文件夹!");
return false;
}
} else {
return false;
}
})
/**
* 生成进度条封装方法
* @param file 文件
* @param percentage 进度值
* @param id_Prefix id前缀
* @param titleName 标题名
*/
function getProgressBar(file, percentage, id_Prefix, titleName) {
var $li = $('#' + file.id), $percent = $li.find('#' + id_Prefix + '-progress-bar');
// 避免重复创建
if (!$percent.length) {
$percent = $('<div id="' + id_Prefix + '-progress" class="progress progress-striped active">' +
'<div id="' + id_Prefix + '-progress-bar" class="progress-bar" role="progressbar" style="width: 0%">' +
'</div>' +
'</div>'
).appendTo($li).find('#' + id_Prefix + '-progress-bar');
}
var progressPercentage = (percentage * 100).toFixed(2) + '%';
$percent.css('width', progressPercentage);
$percent.html(titleName + ':' + progressPercentage);
}
/**
* 隐藏进度条
* @param file 文件对象
* @param id_Prefix id前缀
*/
function fadeOutProgress(file, id_Prefix) {
$('#' + file.id).find('#' + id_Prefix + '-progress').fadeOut();
}
function clearUploder() {
$("#innerfolderdiv").html("");
if($("#salorid").val()=="" || $("#orderno").val()=="") {
$("#urltbody ").html("<tr><td colspan='7'>暂无数据</td></tr>")
$("#foldershow").removeAttr("checked");
$("#listshow").prop("checked", 'checked');
$("#listdiv").attr("style", "display:block;")
$("#folderdiv").attr("style", "display:none;")
}
allurls = new Array();
allurls1 = new Array();
arr = "";
$("#uploaddatetime").val(today());
flagg = true;
flaggg = false;
goOne1 = true;
goOne = true;
$("#uploader1").show();
$("#uploader").show();
totalFileNum = 0;
totalFileNum1 = 0;
$("#thelist").html("");
$("#showfiletotalnum").html("");
$("#showtotalnumspan").hide();
$("#thelist1").html("");
$("#showfiletotalnum1").html("");
$("#showtotalnumspan1").hide();
uploader.reset();
uploader1.reset();
}
function clearFileData1() {
allurls = new Array();
allurls1 = new Array();
arr = "";
flagg = true;
flaggg = false;
goOne1 = true;
goOne = true;
totalFileNum = 0;
totalFileNum1 = 0;
$("#thelist").html("");
$("#showfiletotalnum").html("");
$("#showtotalnumspan").hide();
$("#thelist1").html("");
$("#showfiletotalnum1").html("");
$("#showtotalnumspan1").hide();
uploader.reset();
uploader1.reset();
}
2.这里贴上我的css代码
//进度条面板CSS
#thelist {
border: 1px solid #9AC0CD;
width: 800px;
height: 500px;
Margin: 2px;
padding: 3px;
z-index: 1006;
background-color: #E0EEEE;
position: absolute;
top: 15%;
left: 12%;
overflow-y: scroll;
}
四.这里贴上我的后端application.properties代码
#REDIS配置 这个REDIS我记得在大文件分断上传是用到了,但程序里没有看到,因为时间太久了,也忘了,不过还是贴上
# Redis服务器地址
spring.redis.host=127.0.0.1
# Redis服务器连接端口
spring.redis.port=6379
# Redis服务器连接密码(默认为空)
spring.redis.password=
# 连接池最大连接数(使用负值表示没有限制)
spring.redis.jedis.pool.max-active=30
# 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.jedis.pool.max-wait=10000
# 连接池中的最大空闲连接
spring.redis.jedis.pool.max-idle=10
# 连接超时时间(毫秒) 10秒
spring.redis.timeout=10000
#文件上传分片设置(必须)
spring.servlet.multipart.max-file-size=100MB
spring.servlet.multipart.max-request-size=100MB
spring.thymeleaf.reactive.max-chunk-size=5242880 //这个是5MB,一定要与前端那个chunk-size大小一样,前端是传输的大小,后端是接收的大小,不一至话会造成文件流丢失或错误
五,这贴上我的springMVC代码
/**
* 上传文件
*
* @param param
* @param request
* @return
* @throws Exception
*/
@RequestMapping(value = "/uploadFile", method = RequestMethod.POST)
@ResponseBody
public ResponseEntity uploadFile(MultipartFileParam param, HttpServletRequest request, HttpSession session) throws Exception {
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
UserInfo userInfo = (UserInfo) session.getAttribute("account");
DownloadView view = new DownloadView();
if (isMultipart) {
logger.info("上传文件start。");
try {
// 方法1
//storageService.uploadFileRandomAccessFile(param);
// 方法2 这个更快点
view = fileUploadAndDownServ.uploadFileByMappedByteBuffer1(param, userInfo);
} catch (Exception e) {
e.printStackTrace();
logger.error("文件上传失败。{}", param.toString());
throw e;
}
logger.info("上传文件end。");
}
return ResponseEntity.ok().body("上传成功。");
}
六,这里贴上我的MultipartFileParam 代码
public class MultipartFileParam implements Serializable {
private static final long serialVersionUID = 3659911280472399948L;
private String orderNo;
private String salor;
private String webkitRelativePath;
private String projectName;
private String filedescribtion;
private String remark;
private String modifyreason;
private String md5;
private String webkitRelativePaths;
private String fileNames;
private String randomNum;
private String saveFolderName;
// 用户id
private String uid;
//任务ID
private String id;
//总分片数量
private int chunks;
//当前为第几块分片
private int chunk;
//当前分片大小
private long size = 0L;
//文件名
private String name;
//分片对象
private MultipartFile file;
}
//GET和SET方法就不贴上了,大家自行补上
七,这里贴上我的业务逻辑代码(重点)
// 保存文件的根目录
private Path rootPaht;
//这个必须与前端设定的值一致
@Value("${spring.thymeleaf.reactive.max-chunk-size}")
private long CHUNK_SIZE;
@Value("${spring.servlet.multipart.location}")
private String finalDirPath;
@Transactional(rollbackFor = Exception.class)
public DownloadView uploadFileByMappedByteBuffer1(MultipartFileParam param, UserInfo userInfo) throws Exception {
File tmpDir = null;
String uploadDirPath = finalDirPath;
String fileName = param.getName();
//根据业务员订单号设计师看有没有文件夹
List<FilemanUrl> oldFileUrls = new ArrayList<FilemanUrl>();
//根据业务员订单号设计师看有没有文件夹
List<String> urlStr = new ArrayList<String>();
//根据业务员订单号设计师看有没有文件夹
List<FileManFileInfo> fileManFileInfo = fileUploadAndDownMapper.isSameOrderNoandOtherMessage(userInfo.getUserName(), param.getOrderNo(), param.getSalor());
String pointFolder = null;
boolean f = true;
if (fileManFileInfo.size() > 0) { //有文件夹
oldFileUrls = fileUploadAndDownMapper.findFileUrlByFileInFoData(fileManFileInfo.get(0).getId());
for (FilemanUrl fu : oldFileUrls) {
if (param.getSaveFolderName() != null) {
if (param.getSaveFolderName() != "" && f) {
if (fu.getLogur1().contains("/" + param.getSaveFolderName() + "/")) {
pointFolder = fu.getLogur1();
f = false;
}
}
}
urlStr.add(fu.getLogur1());
}
if (pointFolder != null && pointFolder.length() > 0 && !param.getSaveFolderName().equals("")) {//代表为用户指定目录
int lia = pointFolder.indexOf("/" + param.getSaveFolderName() + "/");
pointFolder = pointFolder.substring(0, lia + param.getSaveFolderName().length() + 1);
tmpDir = new File(uploadDirPath + pointFolder);
} else {
String oldPath = null;
Integer pointindex = null;
String oldsPath = null;
oldPath = urlStr.get(0);
pointindex = StringUtils.ordinalIndexOf(oldPath, "/", 5);
oldsPath = oldPath.substring(0, pointindex + 1);
tmpDir = new File(uploadDirPath + oldsPath);
}
} else {//如果没有文件夹,直接当成新文件全部存.
tmpDir = new File(uploadDirPath + userInfo.getUserName() + "/" + formateString(new Date()) + "/" + param.getSalor() + "/"
+ param.getRandomNum() + "/" + param.getOrderNo() + "/");
}
File tmpFile = new File(tmpDir, fileName);
if (fileName != null) {
if (!tmpDir.exists()) {
tmpDir.mkdirs();
}
RandomAccessFile tempRaf = new RandomAccessFile(tmpFile, "rw");
FileChannel fileChannel = tempRaf.getChannel();
//写入该分片数据
long offset = CHUNK_SIZE * param.getChunk();
byte[] fileData = param.getFile().getBytes();
try {
MappedByteBuffer mappedByteBuffer = fileChannel.map(FileChannel.MapMode.READ_WRITE, offset, fileData.length);
mappedByteBuffer.put(fileData);
// 释放
FileMD5Util.freedMappedByteBuffer(mappedByteBuffer);
fileChannel.close();
tempRaf.close();
mappedByteBuffer.clear();
boolean isOk = checkAndSetUploadProgress(param, uploadDirPath);
if (isOk) {
// boolean flag = renameFile(tmpFile, fileName);
System.out.println("upload complete !! 可以删掉CONF文件 fileName");
boolean isdeleteconf = deleteFile(uploadDirPath.concat(fileName).concat(".conf"));
}
} catch (Exception e) {
e.printStackTrace();
throw e;
} finally {
boolean isdeleteconf1 = deleteFile(uploadDirPath.concat(fileName).concat(".conf"));
}
}
return null;
}
/**
* 上传完成,删除片文件
*
* @param fileName 要删除的文件的文件名
* @return 单个文件删除成功返回true,否则返回false
*/
private boolean deleteFile(String fileName) throws Exception {
File file = new File(fileName);
// 如果文件路径所对应的文件存在,并且是一个文件,则直接删除
if (file.exists() && file.isFile()) {
if (file.delete()) {
System.out.println("删除单个文件" + fileName + "成功!");
return true;
} else {
System.out.println("删除单个文件" + fileName + "失败!");
return false;
}
} else {
System.out.println("删除单个文件失败:" + fileName + "不存在!");
return false;
}
}
/**
* 检查并修改文件上传进度
*
* @param param
* @param uploadDirPath
* @return
* @throws
*/
private boolean checkAndSetUploadProgress(MultipartFileParam param, String uploadDirPath) throws IOException {
String fileName = param.getName();
File confFile = new File(uploadDirPath, fileName + ".conf");
RandomAccessFile accessConfFile = new RandomAccessFile(confFile, "rw");
//把该分段标记为 true 表示完成
System.out.println("set part " + param.getChunk() + " complete");
accessConfFile.setLength(param.getChunks());
accessConfFile.seek(param.getChunk());
accessConfFile.write(Byte.MAX_VALUE);
//completeList 检查是否全部完成,如果数组里是否全部都是(全部分片都成功上传)
byte[] completeList = FileUtils.readFileToByteArray(confFile);
byte isComplete = Byte.MAX_VALUE;
for (int i = 0; i < completeList.length && isComplete == Byte.MAX_VALUE; i++) {
//与运算, 如果有部分没有完成则 isComplete 不是 Byte.MAX_VALUE
isComplete = (byte) (isComplete & completeList[i]);
System.out.println("check part " + i + " complete?:" + completeList[i]);
}
accessConfFile.close();
if (isComplete == Byte.MAX_VALUE) {
stringRedisTemplate.opsForHash().put(Constants.FILE_UPLOAD_STATUS, param.getMd5(), "true");
stringRedisTemplate.opsForValue().set(Constants.FILE_MD5_KEY + param.getMd5(), uploadDirPath + "/" + fileName);
return true;
} else {
if (!stringRedisTemplate.opsForHash().hasKey(Constants.FILE_UPLOAD_STATUS, param.getMd5())) {
stringRedisTemplate.opsForHash().put(Constants.FILE_UPLOAD_STATUS, param.getMd5(), "false");
}
if (stringRedisTemplate.hasKey(Constants.FILE_MD5_KEY + param.getMd5())) {
stringRedisTemplate.opsForValue().set(Constants.FILE_MD5_KEY + param.getMd5(), uploadDirPath + "/" + fileName + ".conf");
}
return false;
}
}
效果图
-