思路:将大文件分片上传,例如将一个4g文件分成8个512M的文件放在某个文件夹中,然后将四个文件用流的方式按顺序再合成一个4g的文件,然后再将这个临时的文件夹和碎片文件都删除掉。
1.js文件中webuploader初始化
//按钮1
uploader = WebUploader.create({
auto: true, // 选完文件后,是否自动上传
swf: swfUrl, // swf文件路径
server: '/big-single-file-upload-json', // 文件接收服务端
pick:{
id:'#file_upload'
},// 选择文件的按钮。
fileSingleSizeLimit : 8192*1024*1024, //单文件最大8GB
// duplicate :true, //重复上传同一个文件
chunked: true,
chunkSize:512*1024*1024,//单个分片为512M
threads:1,
disableGlobalDnd: true,
timeout : 1*60*60*1000, //超时1小时
method : 'POST',
});
uploader.on( 'uploadProgress', function( file, percentage ) {
//上传时进度变化回调,以下代码仅供参考
$("#progress").text("");
$("#progress").text("上传进度:"+(percentage * 100).toFixed(2) + '%');
if(percentage==1){
$("#progress").text("文件上传完成!");
}
});
uploader.on( 'uploadSuccess', function( file ,data, response) {
//上传成功回调,填充自己的代码
});
uploader.on( 'uploadComplete', function(file,data) {
//上传完成回调,填充自己的代码
});
}
2.Controller接收方法
@RequestMapping(value="/big-single-file-upload-json", method = RequestMethod.POST)
@ResponseBody
public Object doUploadFilePost(MultipartHttpServletRequest request,Integer chunk,Integer chunks) throws Exception{
LinkedList<FileMeta> files = new LinkedList<FileMeta>();
FileMeta fileMeta = null;
Iterator<String> itr = request.getFileNames();
MultipartFile mpf = null;
String filePath = "D:/workplace/myproject/files";
String targetFile = "";
String fileTypeAllow = null;
Pattern r = null;
if(fileTypeAllow!=null){
// 创建 Pattern 对象
r = Pattern.compile(fileTypeAllow);
}
List<File> filesList = new ArrayList<File>();
if(chunk==null&&chunks==null){//没有分片 直接保存
while(itr.hasNext()){
// get next MultipartFile
mpf = request.getFile(itr.next());
String fileType = getFileType(mpf.getOriginalFilename());
if(r!=null){
Matcher m = r.matcher(fileType);
if(!m.lookingAt()){
throw new Exception("File type not allowed!");
}
}
//if files > 10 remove the first from the list
if(files.size() >= 10)
files.pop();
//create new fileMeta
fileMeta = new FileMeta();
fileMeta.setFileName(mpf.getOriginalFilename());
//fileMeta.setFileSize(mpf.getSize()/1024+" Kb");
fileMeta.setFileType(fileType);
UUID uuid = UUID.randomUUID();
targetFile = filePath+File.separator+uuid+"."+fileType;
fileMeta.setFileUrl(targetFile );
fileMeta.setFileSize(mpf.getSize()+"");
try {
File file = new File(targetFile);
filesList.add(file);
FileCopyUtils.copy(mpf.getBytes(), new FileOutputStream(targetFile));
String width = request.getParameter("width");
if(!Strings.isNullOrEmpty(width)){
ImageScale.resize(file, file, Integer.parseInt(width), 0.5f);
}
fileMetaService.saveFile(fileMeta);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//2.4 add to files
files.add(fileMeta);
}
if("text/*".equals(request.getHeader("Accept"))){
String result = "{'fileName':'"+fileMeta.getFileName()+"','fileUrl':'"+fileMeta.getFileUrl().replace("\\", "/")
+"','id':'"+fileMeta.getId()+"','fileSize':'"+fileMeta.getFileSize()+"'}";
return result;
}
else if("*/*".equals(request.getHeader("Accept"))){
return fileMeta;
}
return fileMeta;
}else{
try {
while(itr.hasNext()){
// get next MultipartFile
mpf = request.getFile(itr.next());
String fileType = getFileType(mpf.getOriginalFilename());
String fileName = mpf.getOriginalFilename().replace("."+fileType, "");
File file2 = new File(filePath+"/"+fileName+"/"+chunk+"."+fileType);
if(!file2.exists()){
file2.mkdirs();
}
try {
//保存每一个分片
mpf.transferTo(file2);
} catch (Exception e) {
e.printStackTrace();
}
//判断是否最后一个分片
if(chunk==(chunks-1)){
FileOutputStream fileOutputStream=null;
BufferedOutputStream bufferedOutputStream=null;
BufferedInputStream inputStream=null;
UUID uuid = UUID.randomUUID();
targetFile = filePath+File.separator+uuid+"."+fileType;
//Tomcat代码
// String fileurl = targetFile.replace(dir, "");
String fileurl = targetFile.replace(FilePath.getSystemRootPath(), "");
File newFile=new File(targetFile);
//先判断文件的父目录是否存在,不存在需要创建;否则报错
if(!newFile.getParentFile().exists()){
newFile.getParentFile().mkdirs();
newFile.createNewFile();//创建文件
}
//创建流
fileOutputStream=new FileOutputStream(newFile, true);
//创建文件输入缓冲流
bufferedOutputStream=new BufferedOutputStream(fileOutputStream);
byte[] buffer = new byte[1024];//一次读取1024个字节
File tempFiles=new File(filePath+"/"+fileName);
File [] filesArr=tempFiles.listFiles();
//对这个文件数组进行排序
Arrays.sort(filesArr, new Comparator() {
@Override
public int compare(Object o1, Object o2) {
int o1Index = Integer.parseInt(((File)o1).getName().split("\\.")[0]);
int o2Index = Integer.parseInt(((File)o2).getName().split("\\.")[0]);
if (o1Index > o2Index) {
return 1;
} else if (o1Index == o2Index){
return 0;
} else {
return -1;
}
}
});
Long newFileSize = 0L;
for (int i = 0; i < filesArr.length; i ++) {
File fileTemp=filesArr[i];
newFileSize=(new BigDecimal(newFileSize).add(new BigDecimal(fileTemp.length()))).longValue();
inputStream = new BufferedInputStream(new FileInputStream(fileTemp));
int readcount;
while ((readcount = inputStream.read(buffer)) > 0) {
bufferedOutputStream.write(buffer, 0, readcount);
bufferedOutputStream.flush();
}
inputStream.close();
}
bufferedOutputStream.close();
//删除分块文件
//一个文件夹一起删了
for (int i = 0; i < filesArr.length; i ++) {
filesArr[i].delete();
}
tempFiles.delete();
//记录
fileMeta = new FileMeta();
fileMeta.setFileName(mpf.getOriginalFilename());
fileMeta.setFileType(fileType);
fileMeta.setFileUrl(fileurl);
fileMeta.setFileSize(newFileSize+"");
fileMetaService.saveFile(fileMeta);
}
if("text/*".equals(request.getHeader("Accept"))){
String result = "{'fileName':'"+fileMeta.getFileName()+"','fileUrl':'"+fileMeta.getFileUrl().replace("\\", "/")
+"','id':'"+fileMeta.getId()+"','fileSize':'"+fileMeta.getFileSize()+"'}";
return result;
}
else if("*/*".equals(request.getHeader("Accept"))){
return fileMeta;
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return fileMeta;
}
}
private String getFileType(String originalFilename) {
return originalFilename.substring(originalFilename.lastIndexOf('.')+1).toLowerCase();
}