最后发现plupload可以上传超4G,并且Silverlight,flash,html4,html5模式上传
Silverlight 安装微软的Silverlight
flash只要浏览器支持flash就行,但存在一个bug,文件超过4G时,选择文件后上传列表不响应,只能推拽进上传列表
html5浏览器支持
以上只需要存在一个即可上传
不废话,直接看代码,希望大家指教
找到plupload.dev.js
修改成如下:
onUploadFile function onUploadFile(up, file) { var url = up.settings.url, chunkSize = up.settings.chunk_size, retries = up.settings.max_retries, features = up.features, offset = 0, blob; if (file.name != null) { $.get("ckeck", { filename : file.name, chunk_size:up.settings.chunk_size, }, function(data) { offset = data.off; }); }
断点续传需要数据库的支持,因为是测试使用简单的JDBC操作数据库
package db; import java.sql.*; public class Database { private String dbDriver="com.mysql.jdbc.Driver"; private String sConnStr = "jdbc:mysql://localhost:3306/upload?useUnicode=true&characterEncoding=UTF-8"; public Connection connect = null; public ResultSet rs=null; public Database() { try { Class.forName(dbDriver).newInstance(); connect = DriverManager.getConnection(sConnStr,"root",""); } catch (Exception ex) { System.out.println(""); } } public ResultSet executeQuery(String sql) { System.out.println(sql); try{ connect=DriverManager.getConnection(sConnStr,"root",""); Statement stmt=connect.createStatement(); rs=stmt.executeQuery(sql); }catch(SQLException ex){ System.err.println(ex.getMessage()); } return rs; } public void executeUpdate(String sql) { System.out.println(sql); Statement stmt=null; rs=null; try { connect=DriverManager.getConnection(sConnStr,"root",""); stmt=connect.createStatement(); stmt.executeUpdate(sql); stmt.close(); connect.close(); } catch(SQLException ex) { System.err.println(ex.getMessage()); } } }
plupload是分块上传文件,记录文件上传到哪块,以便断点
package gson.demo; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.sql.ResultSet; import java.util.List; import java.util.UUID; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileUploadException; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.apache.commons.io.FileUtils; import org.apache.commons.io.FilenameUtils; import db.Database; public class UploaderServlet extends HttpServlet { private static final long serialVersionUID = 1L; String repositoryPath; String uploadPath; @SuppressWarnings("unchecked") public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setCharacterEncoding("UTF-8"); Integer schunk = null;// 分割块数 Integer schunks = null;// 总分割数 String name = null;// 文件名 BufferedOutputStream outputStream = null; if (ServletFileUpload.isMultipartContent(request)) { try { DiskFileItemFactory factory = new DiskFileItemFactory(); factory.setSizeThreshold(1024); factory.setRepository(new File(repositoryPath));// 设置临时目录 ServletFileUpload upload = new ServletFileUpload(factory); upload.setHeaderEncoding("UTF-8"); upload.setSizeMax(5 * 1024 * 1024 * 1024);// 设置附近大小 Listitems = upload.parseRequest(request); // 生成新文件名 String newFileName = null; for (FileItem item : items) { if (!item.isFormField()) {// 如果是文件类型 name = newFileName;// 获得文件名 if (name != null) { String nFname = newFileName; if (schunk != null) { nFname = schunk + "_" + name; } File savedFile = new File(uploadPath, nFname); item.write(savedFile); } } else { // 判断是否带分割信息 if (item.getFieldName().equals("chunk")) { schunk = Integer.parseInt(item.getString()); System.out.println(schunk); } if (item.getFieldName().equals("chunks")) { schunks = Integer.parseInt(item.getString()); } if (item.getFieldName().equals("name")) { newFileName = item.getString(); } } } Database db = new Database(); if (schunk != null && schunk == 0) { String ckcksql = "select * from file where filename ='" + newFileName + "'"; db.executeQuery(ckcksql); if (db.rs.first()) { } else { String sql = "INSERT INTO file (filename,schunk,schunks) VALUES ('" + newFileName + "'," + schunk + "," + schunks + ")"; db.executeUpdate(sql); } } else { String sql = "update file set schunk=" + schunk + " where filename ='" + newFileName + "'"; db.executeUpdate(sql); } if (schunk != null && schunk + 1 == schunks) { outputStream = new BufferedOutputStream( new FileOutputStream(new File(uploadPath, newFileName))); // 遍历文件合并 for (int i = 0; i < schunks; i++) { File tempFile = new File(uploadPath, i + "_" + name); byte[] bytes = FileUtils.readFileToByteArray(tempFile); outputStream.write(bytes); outputStream.flush(); tempFile.delete(); } outputStream.flush(); } response.getWriter() .write("{\"status\":true,\"newName\":\"" + newFileName + "\"}"); } catch (FileUploadException e) { e.printStackTrace(); response.getWriter().write("{\"status\":false}"); } catch (Exception e) { e.printStackTrace(); response.getWriter().write("{\"status\":false}"); } finally { try { if (outputStream != null) outputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } } @Override public void init(ServletConfig config) throws ServletException { repositoryPath = FileUtils.getTempDirectoryPath(); System.out.println("临时目录:" + repositoryPath); uploadPath = config.getServletContext().getRealPath( config.getInitParameter("uploadPath")); System.out.println("目录:" + uploadPath); File up = new File(uploadPath); if (!up.exists()) { up.mkdir(); } } }
上传之前检测文件是否上传过,注:修改文件后再上传未作处理,可获取文件大小存库,对比,如果大小改变,不再断点续传,重新上传
数据库设计(Mysql)
package gson.demo; import java.io.File; import java.io.IOException; import java.sql.ResultSet; import java.sql.SQLException; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.io.FileUtils; import db.Database; public class CkeckFileServlet extends HttpServlet { String repositoryPath; String uploadPath; @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // TODO Auto-generated method stub String fileName=new String(req.getParameter("filename").getBytes("8859_1"),"utf-8"); String chunk_size = req.getParameter("chunk_size"); System.out.println(chunk_size); System.out.println(fileName); resp.setContentType("text/json; charset=utf-8"); Database db = new Database(); String sql = "select * from file where filename = '" + fileName+"'"; ResultSet RS_result = db.executeQuery(sql); try { if (db.rs.first()) { int schunk = RS_result.getInt("schunk"); //删除最近一个分块,防止最后一个分块未上传之前被断开上传,一般不会发生 deleteFile(uploadPath+schunk+"_"+fileName); long off = schunk * Long.parseLong(chunk_size); resp.getWriter().write("{\"off\":"+off+"}"); } else { resp.getWriter().write("{\"off\":0}"); } } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // TODO Auto-generated method stub doGet(req, resp); } @Override public void init(ServletConfig config) throws ServletException { repositoryPath = FileUtils.getTempDirectoryPath(); uploadPath = config.getServletContext().getRealPath( config.getInitParameter("uploadPath")); File up = new File(uploadPath); if (!up.exists()) { up.mkdir(); } } public boolean deleteFile(String sPath) { boolean flag = false; File file = new File(sPath); // 路径为文件且不为空则进行删除 if (file.isFile() && file.exists()) { file.delete(); flag = true; } return flag; } }
首页
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme() + "://"+ request.getServerName() + ":" + request.getServerPort()+ path + "/"; %>GodSon Easyui 结合Pluplaod插件的上传演示 GodSon Easyui 结合Pluplaod插件的上传演示
不分割文件上传 分割文件上传
上传页面
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>文件上传
除了上面说到的,修改文件之后上传未处理,还有一个中文乱码未处理,
if (item.getFieldName().equals("name")) { newFileName = item.getString(); }
修改编码
newFileName = new String(item.getString().getBytes("8859_1"),"utf-8");
对于修改文件之后,继续上传,在实际应用中我使用的是MD5对比,效果还不错