当前位置: 首页 > 工具软件 > Plupload > 使用案例 >

plupload断点续传

梁昊天
2023-12-01
[size=large][b]1. 简介[/b][/size]
Plupload是不支持断点续传的,但是他支持分片上传,因此我们只需要打开其分片上传后,在文件上传之前请求一个服务器当前文件已上传的大小,如果上传大小为0则认为没有上传过,重新上传,如果上传文件大小大于0则从已上传的切片的下一个切片开始上传。
[b][size=large]2. 修改plupload[/size][/b]
[b]1. 判断是否上传过[/b]
修改plupload.js,在onUploadFile方法中添加请求
if (file.name && chunkSize) {
$.ajax({
type: "GET",
async : false ,
url: "upload.do",
data: {
name:file.name,
askBreakpoint:true,
resumableUpload:true,
fileSize:file.size,
lastModifiedDate:file.lastModifiedDate.getTime()
},
success: function(data){
offset = Number(data);
}
});
}

注意: 此处offset = Number(data)如果是ie9+浏览器可以不用进行number转换,但是ie8中会出现只传一片的情况,需要把offset转为number才可以
[b]2. 添加断点续传参数[/b]
if (chunkSize) {
formData.append("fileSize", file.size);
formData.append("lastModifiedDate",file.lastModifiedDate.getTime());
formData.append("resumableUpload", true);
}

[b]3. 添加interceptor[/b]

[b](1)如果是请求已上传文件大小,则查找文件,返回已上传文件大小[/b]

String askBreakPoint = request.getParameter(ASK_BREAKPOINT);
if (StringUtils.isNotEmpty(resumableUpload) && StringUtils.isNotEmpty(askBreakPoint)) {
if (StringUtils.isNotEmpty(askBreakPoint)) {
File file = new File(getBreak_Point_TempDir(servletContext) + File.separator + getFullMD5FileName(request));
GboatAppContext.output(file.exists() ? file.length() : 0);
return null;
}
}


[b](2)如果是断点续传,则进行上传[/b]

if (!StringUtils.isEmpty(resumableUpload)) {
// 当前片
String currentChunk = request.getParameter(CURRENT_CHUNK);
String chunks = request.getParameter(CHUNKS);
// 请求上传
if (StringUtils.isNotEmpty(currentChunk)) {
File file = new File(getBreak_Point_TempDir(servletContext) + File.separator
+ getFullMD5FileName(request));
File appendedFile = acceptedFiles.get(0);
boolean isLastChunck = Integer.valueOf(currentChunk) >= (Integer.valueOf(chunks) - 1);
// 追加:如果文件存在
if (file.exists()) {
try {
long size = Long.valueOf(request.getParameter(RESUMABLE_SIZE));
long uploadedSize = file.length();
if (!(isLastChunck && uploadedSize == size)) {
// if last chunk and uploaded size = file size, don't append
FileUtil.appendFile(file, appendedFile);
}
} catch (Exception e) {
response.setStatus(501);
return null;
}
} else {
// 新建:如果文件不存在创建并写入
File outFile = new File(file.getPath());
try { FileUtil.writeFileToDisk(acceptedFiles.get(0), outFile);
} catch (Exception e) {
response.setStatus(501);
return null;
}
}
// 如果判断当前的chunks,如果达到最大,交给action处理,如果没有达到最大返回
if (!isLastChunck) {
GboatAppContext.output(Boolean.TRUE);
return null;
} else {
// 把最终上传的总文件告诉action
List<File> resultList = new ArrayList<File>();
resultList.add(file);
filesToCleanup.add(file);// 需要手动清除已经上传的文件
params.put(inputName, resultList.toArray(new File[acceptedFiles.size()]));
}
}
}


[b](3)断点续传的临时文件名根据文件名、文件大小、文件修改时间组合求散列值[/b]

private String getFullMD5FileName(HttpServletRequest request) throws Exception {
// 文件名字,文件的修改时间,文件的大小
String fileNameUpload = request.getParameter(RESUMABLE_FILENAME);
String modificationDate = request.getParameter(RESUMABLE_MODIFICATION_DATE);
String size = request.getParameter(RESUMABLE_SIZE);
// 散列形成文件名
String md5FileName = MD5Util.getMD5String(fileNameUpload + size + modificationDate);
// 散列后完整文件名
String fullMD4FileName = md5FileName + fileNameUpload.substring(fileNameUpload.lastIndexOf("."));
return fullMD4FileName;
}


[b]4. 修改上传action代码[/b]
如果是断点续传那么上传文件的fileFileName不是真正的文件名,name参数,因此需要替换下
String resumableUpload = request.getParameter(RESUMABLE_UPLOAD);
if (StringUtils.isNotEmpty(resumableUpload)) {
fileFileName = name;
}

[b]5. 兼容ie8 ie9[/b]
Plupload分片上传使用了html5的新特性,针对ie8 ie9等不支持html5的情况,采用flash等进行分片上传,但是plupload不建议采用flash分片上传,因为flash在分片上传读取待上传文件时不能读取一部分,只能将文件全部加载到内存中再进行分片上传,会消耗客户端内存。因此默认情况没有打开分片上传,而且根据他官方给的强制打开方法也不好使,最终修改了moxie
slice_blob: function(value) {
return value && I.mode === 'client';
},

[b]由brower改为client[/b]


[b]参考 [/b]:http://gbguanbo.iteye.com/blog/2043264
 类似资料: