百度Web Uploader组件实现文件上传之分片上传(一)

阅读更多

当网络问题导致传输错误时,只需要重传出错分片,而不是整个文件。另外分片传输能够更加实时的跟踪上传进度。多的不说了直接怼代码


前端是三个监听:一个是获取md5,一个是分片,最后一个是合并代码



fileupload.html








  


选择文件


后端:一个保持文件servlet,一个判断分片和合并文件servelt

保持文件servlet


import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.Path;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
@Path("/fileupload")
public class ZFileCommand extends HttpServlet{
	private static final long serialVersionUID = -2720014423604662780L;
		// 1.文件上传路径
		private static final String UPLOAD_DIRECTORY = "D:/文件上传";
		// 2.设置临时存储文件大小,当超过大小时,将先存储超出大小文件在临时目录
		private static final int MEMORY_THRESHOLD = 1024 * 1024 * 30; 
		// 3.设置最大文件上传值
		private static final int MAX_FILE_SIZE = 1024 * 1024 * 2000; 
		// 4.最大请求值
		private static final int MAX_REQUEST_SIZE = 1024 * 1024 * 2048; 
		
	public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
			request.setCharacterEncoding("utf-8");
			response.setCharacterEncoding("utf-8");
			response.setContentType("text/html;charset=utf-8");
			//获取文件名
		    String filename=request.getParameter("name");
		    //防止读取name名乱码
		    filename=new String(filename.getBytes("iso-8859-1"),"utf-8");
		    //在控制台打印文件名
		    System.out.println("文件名:"+filename);
		     //设置文件MIME类型  
		    response.setContentType(getServletContext().getMimeType(filename));  
		    //设置Content-Disposition  
		    String realName = filename.substring(filename.indexOf("_")+1);
		    response.setHeader("Content-Disposition", "attachment;filename="+realName);

		    //输入流为项目文件,输出流指向浏览器
		    InputStream is=new FileInputStream(UPLOAD_DIRECTORY+filename);
		    ServletOutputStream os =response.getOutputStream();
		    /*
		     * 设置缓冲区
		     * is.read(b)当文件读完时返回-1
		     */
		    int len=-1;
		    byte[] b=new byte[1024];
		    while((len=is.read(b))!=-1){
		        os.write(b,0,len);
		    }
		    //关闭流
		    is.close();
		    os.close();
		    
		}
	
	/**
	 * @摘要 提供文件上传的方法
	 */
	public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
		//1.设置字符编码为utf-8
		request.setCharacterEncoding("utf-8");
		response.setCharacterEncoding("utf-8");
		response.setContentType("text/html;charset=utf-8");
		// 2.检测是否为多媒体上传
		if (!ServletFileUpload.isMultipartContent(request)) {
			// 2.1如果不是则停止
			PrintWriter writer = response.getWriter();
			writer.println("Error: 表单必须包含 enctype=multipart/form-data");
			writer.flush();
			return  ;
		}
		// 3.配置上传参数
		DiskFileItemFactory factory = new DiskFileItemFactory();
		//4. 设置内存临界值 - 超过后将产生临时文件并存储于临时目录中
		factory.setSizeThreshold(MEMORY_THRESHOLD);
		// 5.设置临时存储目录 java.io.tmpdir默认的临时文件路径为服务器的temp目录
		factory.setRepository(new File(System.getProperty("java.io.tmpdir")));

		ServletFileUpload upload = new ServletFileUpload(factory);

		// 6.设置最大文件上传值
		upload.setFileSizeMax(MAX_FILE_SIZE);

		// 7.设置最大请求值 (包含文件和表单数据)
		upload.setSizeMax(MAX_REQUEST_SIZE);

		//8. 如果目录不存在则创建
		File uploadDir = new File(UPLOAD_DIRECTORY);
		if (!uploadDir.exists()) {
			uploadDir.mkdir();
		}
		String fileMd5 = null;  
        String chunk = null;  
		try {
			// 10.解析请求的内容提取文件数据
			List formItems = upload.parseRequest(request);
				// 10.1迭代表单数据
			if (formItems != null && formItems.size() > 0) {
				for (FileItem item : formItems) {
					if (item.isFormField()) {
						  String fieldName = item.getFieldName();  
		                    if(fieldName.equals("fileMd5")){  
		                        fileMd5 = item.getString("utf-8");  
		                    }  
		                    if(fieldName.equals("chunk")){  
		                        chunk = item.getString("utf-8");  
		                    }  
						
	                }else{
	                	String nFileName = new File(item.getName()).getName();
	                    
	                	File file = new File(UPLOAD_DIRECTORY+"/"+fileMd5);  
	                   
	                    if(!file.exists()){  
	                        file.mkdir();  
	                    }  
						nFileName=nFileName.substring(0,nFileName.lastIndexOf("."))	;

						item.write(new File(UPLOAD_DIRECTORY+"/"+fileMd5+"/"+chunk));
						
						item.delete();					    	
	                }
					
					}
				}  
		} catch (Exception ex) {
			PrintWriter writer=response.getWriter();
			writer.print("error");
		}
	}
}


一个判断分片和合并文件servelt
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class mergeFile extends HttpServlet {
	private static final long serialVersionUID = 1L;
	private static final String UPLOAD_DIRECTORY = "D:/文件上传";

	   public void doGet(HttpServletRequest request, HttpServletResponse response)  
	            throws ServletException, IOException {  
	        super.doGet(request, response);  
	        doPost(request, response);  
	          
	    }  
	  
	    public void doPost(HttpServletRequest request, HttpServletResponse response)   throws ServletException, IOException {  
	        String savePath = this.getServletConfig().getServletContext()  
	                .getRealPath("");  
	        String folad = "uploads";  
	        savePath = "D:/文件上传";  
	          
	        String action = request.getParameter("action");  
	          
	        if(action.equals("mergeChunks")){  
	            //合并文件  
	            //需要合并的文件的目录标记  
	            String fileMd5 = request.getParameter("fileMd5");  
	              
	            //读取目录里的所有文件  
	            File f = new File(savePath+"/"+fileMd5);  
	            File[] fileArray = f.listFiles(new FileFilter(){  
	                //排除目录只要文件  
	                public boolean accept(File pathname) {  
	                    // TODO Auto-generated method stub  
	                    if(pathname.isDirectory()){  
	                        return false;  
	                    }  
	                    return true;  
	                }  
	            });  
	              
	            //转成集合,便于排序  
	            List fileList = new ArrayList(Arrays.asList(fileArray));  
	            Collections.sort(fileList,new Comparator() {  
	                public int compare(File o1, File o2) {  
	                    // TODO Auto-generated method stub  
	                    if(Integer.parseInt(o1.getName()) < Integer.parseInt(o2.getName())){  
	                        return -1;  
	                    }  
	                    return 1;  
	                }  
	            });  
	            //UUID.randomUUID().toString()-->随机名  
	            File outputFile = new File(savePath+"/"+fileMd5+".mp4");  
	            //创建文件  
	            outputFile.createNewFile();  
	            //输出流  
	            FileChannel outChnnel = new FileOutputStream(outputFile).getChannel();  
	            //合并  
	            FileChannel inChannel;  
	            for(File file : fileList){  
	                inChannel = new FileInputStream(file).getChannel();  
	                inChannel.transferTo(0, inChannel.size(), outChnnel);  
	                inChannel.close();  
	                //删除分片  
	                file.delete();  
	            }  
	            outChnnel.close();  
	            //清除文件夹  
	            File tempFile = new File(savePath+"/"+fileMd5);  
	            if(tempFile.isDirectory() && tempFile.exists()){  
	                tempFile.delete();  
	            }  
	            System.out.println("合并成功");  
	        }else if(action.equals("checkChunk")){  
	            //检查当前分块是否上传成功  
	            String fileMd5 = request.getParameter("fileMd5");  
	            //分块次数
	            String chunk = request.getParameter("chunk");
	            //分块大小
	            String chunkSize = request.getParameter("chunkSize");  
	              
	            File checkFile = new File(savePath+"/"+fileMd5+"/"+chunk);  
	              
	            response.setContentType("text/html;charset=utf-8");  
	            //检查文件是否存在,且大小是否一致  
	            if(checkFile.exists() && checkFile.length()==Integer.parseInt(chunkSize)){  
	                //上传过  
	                response.getWriter().write("{\"ifExist\":1}");  
	            }else{  
	                //没有上传过  
	                response.getWriter().write("{\"ifExist\":0}");  
	            }  
	        }  
	          
	    }  

附件:源码
  • Angular.zip (1.3 MB)
  • 下载次数: 19

你可能感兴趣的:(servlet,文件上传,分片上传,Web,Uploader)