使用webuploader分片上传一个大文件

本文介绍了一种使用WebUploader库实现大文件分片上传的方法,通过将大文件分割成多个小片段,分别上传后再合成完整文件,有效解决了大文件上传的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

思路:将大文件分片上传,例如将一个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();
	}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MrZhouGx

觉得对你有用的话可以支持一下

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值