java 下载 断点续传
1 import java.io.BufferedInputStream; 2 import java.io.File; 3 import java.io.FileInputStream; 4 import java.io.IOException; 5 import java.io.InputStream; 6 import java.io.OutputStream; 7 8 import javax.servlet.ServletException; 9 import javax.servlet.http.HttpServlet; 10 import javax.servlet.http.HttpServletRequest; 11 import javax.servlet.http.HttpServletResponse; 12 13 14 public class DownLoad extends HttpServlet { 15 @Override 16 protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 17 String location = "E:\\upload\\1.rar"; 18 downFile(response,request, location); 19 20 } 21 private void downFile(HttpServletResponse response, HttpServletRequest request, String location){ 22 BufferedInputStream bis = null; 23 try { 24 File file = new File(location); 25 if (file.exists()) { 26 long p = 0L; 27 long toLength = 0L; 28 long contentLength = 0L; 29 int rangeSwitch = 0; // 0,从头开始的全文下载;1,从某字节开始的下载(bytes=27000-);2,从某字节开始到某字节结束的下载(bytes=27000-39000) 30 long fileLength; 31 String rangBytes = ""; 32 fileLength = file.length(); 33 34 // get file content 35 InputStream ins = new FileInputStream(file); 36 bis = new BufferedInputStream(ins); 37 38 // tell the client to allow accept-ranges 39 response.reset(); 40 response.setHeader("Accept-Ranges", "bytes"); 41 42 // client requests a file block download start byte 43 String range = request.getHeader("Range"); 44 if (range != null && range.trim().length() > 0 && !"null".equals(range)) { 45 response.setStatus(javax.servlet.http.HttpServletResponse.SC_PARTIAL_CONTENT); 46 rangBytes = range.replaceAll("bytes=", ""); 47 if (rangBytes.endsWith("-")) { // bytes=270000- 48 rangeSwitch = 1; 49 p = Long.parseLong(rangBytes.substring(0, rangBytes.indexOf("-"))); 50 contentLength = fileLength - p; // 客户端请求的是270000之后的字节(包括bytes下标索引为270000的字节) 51 } else { // bytes=270000-320000 52 rangeSwitch = 2; 53 String temp1 = rangBytes.substring(0, rangBytes.indexOf("-")); 54 String temp2 = rangBytes.substring(rangBytes.indexOf("-") + 1, rangBytes.length()); 55 p = Long.parseLong(temp1); 56 toLength = Long.parseLong(temp2); 57 contentLength = toLength - p + 1; // 客户端请求的是 270000-320000 之间的字节 58 } 59 } else { 60 contentLength = fileLength; 61 } 62 63 // 如果设设置了Content-Length,则客户端会自动进行多线程下载。如果不希望支持多线程,则不要设置这个参数。 64 // Content-Length: [文件的总大小] - [客户端请求的下载的文件块的开始字节] 65 response.setHeader("Content-Length", new Long(contentLength).toString()); 66 67 // 断点开始 68 // 响应的格式是: 69 // Content-Range: bytes [文件块的开始字节]-[文件的总大小 - 1]/[文件的总大小] 70 if (rangeSwitch == 1) { 71 String contentRange = new StringBuffer("bytes ").append(new Long(p).toString()).append("-") 72 .append(new Long(fileLength - 1).toString()).append("/") 73 .append(new Long(fileLength).toString()).toString(); 74 response.setHeader("Content-Range", contentRange); 75 bis.skip(p); 76 } else if (rangeSwitch == 2) { 77 String contentRange = range.replace("=", " ") + "/" + new Long(fileLength).toString(); 78 response.setHeader("Content-Range", contentRange); 79 bis.skip(p); 80 } else { 81 String contentRange = new StringBuffer("bytes ").append("0-") 82 .append(fileLength - 1).append("/") 83 .append(fileLength).toString(); 84 response.setHeader("Content-Range", contentRange); 85 } 86 87 String fileName = file.getName(); 88 response.setContentType("application/octet-stream"); 89 response.addHeader("Content-Disposition", "attachment;filename=" + fileName); 90 91 OutputStream out = response.getOutputStream(); 92 int n = 0; 93 long readLength = 0; 94 int bsize = 1024; 95 byte[] bytes = new byte[bsize]; 96 if (rangeSwitch == 2) { 97 // 针对 bytes=27000-39000 的请求,从27000开始写数据 98 while (readLength <= contentLength - bsize) { 99 n = bis.read(bytes); 100 readLength += n; 101 out.write(bytes, 0, n); 102 } 103 if (readLength <= contentLength) { 104 n = bis.read(bytes, 0, (int) (contentLength - readLength)); 105 out.write(bytes, 0, n); 106 } 107 } else { 108 while ((n = bis.read(bytes)) != -1) { 109 out.write(bytes,0,n); 110 } 111 } 112 out.flush(); 113 out.close(); 114 bis.close(); 115 } else { 116 System.out.println(" location + not found"); 117 } 118 } catch (IOException ie) { 119 } catch (Exception e) { 120 e.printStackTrace(); 121 122 } 123 } 124 }