大文件分割上传
希望大家指点有哪些地方不足!
Html 代码
<div id=""> <form class="form-horizontal" enctype="multipart/form-data" id="formImport"> <!-- 单个文件上传 --> <input type="file" id="xlsFile" name="excelFile" /> </form> </div>
触发上传
submitForm(0,1); //由 0 字节开始上传,命名由第 1 部分开始
js 代码
function submitForm(begin,part){ var file = $('#xlsFile')[0].files[0]; //console.log(file); const LENGTH = 1024 * 1024 * 10;//每次上传的大小 var totalSize = file.size; //文件总大小 var start = begin; //每次上传的开始字节 var end = start + LENGTH; //每次上传的结尾字节 var blob = null; //二进制对象 blob = file.slice(start,end); //截取每次需要上传字节数 formData = new FormData(); //每一次需重新创建 formData.append('file',blob); //添加数据到表单对象中 formData.append('fileName',file.name);//上传文件的名字 formData.append('part',part); //上传第几部分 $.ajax({ url: '${path}/exe/doUploadDatas', type: 'POST', cache: false, data: formData, processData: false, contentType: false }).done(function(result){ if(result.code==200){ start = end; // 累计上传字节数 end = start + LENGTH; // 由上次完成的部分字节开始,添加下次上传的字节数 part++; // 上传文件部分累计 if(start>=totalSize){ //如果上传字节数大于或等于总字节数,结束上传 alert('上传完成!'); //告诉后台上传完成后合并文件 //返回上传文件的存放路径 $.post('${path}/exe/mergetFile',{fileName:file.name,path:result.path},function(result){ if(result.code==200){ alert('合并完成!'); } }); }else{ submitForm(start,part); // 上传字节不等与或大于总字节数,继续上传 } } }).fail(function() { }); }
后台使用了spring mvc
@RequestMapping(value = "/doUploadDatas",method = RequestMethod.POST) @ResponseBody //synchronized public Map<String,Object> doSaveImportDatas(@RequestParam("file") MultipartFile file,String fileName,Integer part) throws Exception{ Map<String, Object> map = new HashMap<String, Object>(); try { //创建存放合并文件 根据需求修改 String path = "D:\\新建文件夹\\source\\temp"; File mkdir = new File(path); if (!mkdir.exists()) { mkdir.mkdirs(); } file.transferTo(new File(path+"\\"+fileName+"-"+part)); map.put("code",200); map.put("path",path); } catch (Exception e) { map.put("error",e.getMessage()); } return map; }
上传完成后的文件是这样的。
合并文件
@RequestMapping("/mergetFile") @ResponseBody public Map<String,Object> mergetFile(String fileName,String path){ Map<String, Object> map = new HashMap<String, Object>(); try { //合并目标路径 根据需求修改 合并文件名 合并来源路径 merge("D:\\新建文件夹\\target\\", fileName, path); map.put("code",200); } catch (Exception e) { map.put("error",e.getMessage()); } return map; }
public static void merge(String targetPath,String targetFileName,String sourcePath) throws IOException{ File file = new File(sourcePath); File[] fileArr = file.listFiles(); String[] arr = new String[fileArr.length]; //这里要注意,要按文件上传完成顺序合并,如果没有按顺序合并。最终的文件是损坏的。 for (int i = 0; i < fileArr.length; i++) { arr[i] = fileArr[i].getPath(); } //根据最后面的部分 按先后顺序排序 for (int i = 0; i < arr.length; i++) { for (int j = 0; j < arr.length-1; j++) { if(Integer.parseInt(arr[i].substring(arr[i].lastIndexOf("-"),arr[i].length())) >Integer.parseInt(arr[j].substring(arr[j].lastIndexOf("-"),arr[j].length()))) { String temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } } } File destFile = new File(targetPath+targetFileName);//合并后的文件 InputStream in = null; OutputStream out = new FileOutputStream(destFile); try { byte[] bytes = new byte[1024*1024]; for (String f : arr) { in = new FileInputStream(f); System.out.println(f); int len = -1; while((len = in.read(bytes))!=-1){ out.write(bytes, 0, len); } } in.close(); out.close(); //删除合并前文件 } catch (FileNotFoundException e) { e.printStackTrace(); } }
转成集合排序会方便点,但是在别人的电脑上测试会有问题
List<File> files = Arrays.asList(fileArr); files.sort((File f1,File f2)->f1.lastModified()-f2.lastModified()>0?1:-1); //按修改日期排序, 这样排序会有问题