java完成文件斷點續傳下載功效。本站提示廣大學習愛好者:(java完成文件斷點續傳下載功效)文章只能為提供參考,不一定能成為您想要的結果。以下是java完成文件斷點續傳下載功效正文
本文實例為年夜家分享了java斷點續傳下載的代碼,供年夜家參考,詳細內容以下
1. Java代碼
//完成文件下載功效 public String downloadFile(){ File dir = new File(filepath);//獲得文件路勁 if(!dir.exists()) { System.out.println("文件途徑毛病"); log.debug("文件途徑毛病"); return "failed";// 斷定文件或文件夾能否存在 } File downloadFile = new File(dir, filename);//在指定目次下查找文件 if(!downloadFile.isFile()){ System.out.println("文件不存在"); log.debug("文件不存在"); return "failed";// 斷定文件或文件夾能否存在 } try { downloadFileRanges(downloadFile); } catch(ClientAbortException e){ System.out.println("銜接被終止"); log.debug("銜接被終止"); } catch (IOException e) { e.printStackTrace(); } return null; } private void downloadFileRanges(File downloadFile) throws IOException { // 要下載的文件年夜小 long fileLength = downloadFile.length(); // 已下載的文件年夜小 long pastLength = 0; // 能否慢車下載,不然為迅雷或其他 boolean isFlashGet = true; // 用於記載須要下載的停止字節數(迅雷或其他下載) long lenEnd = 0; // 用於記載客戶端請求下載的數據規模字串 String rangeBytes = request.getHeader("Range"); //用於隨機讀取寫入文件 RandomAccessFile raf = null; OutputStream os = null; OutputStream outPut = null; byte b[] = new byte[1024]; // 假如客戶端下載要求中包括了規模 if (null != rangeBytes) { // 前往碼 206 response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT); rangeBytes = request.getHeader("Range").replaceAll("bytes=", ""); // 斷定 Range 字串形式 if (rangeBytes.indexOf('-') == rangeBytes.length() - 1) { // 無停止字節數,為慢車 isFlashGet = true; rangeBytes = rangeBytes.substring(0, rangeBytes.indexOf('-')); pastLength = Long.parseLong(rangeBytes.trim()); } else { // 迅雷下載 isFlashGet = false; String startBytes = rangeBytes.substring(0, rangeBytes.indexOf('-')); String endBytes = rangeBytes.substring( rangeBytes.indexOf('-') + 1, rangeBytes.length()); // 已下載文件段 pastLength = Long.parseLong(startBytes.trim()); // 還需下載的文件字節數(從已下載文件段開端) lenEnd = Long.parseLong(endBytes); } } // 告訴客戶端許可斷點續傳,呼應格局為:Accept-Ranges: bytes response.setHeader("Accept-Ranges", "bytes"); // response.reset(); // 假如為第一次下載,則狀況默許為 200,呼應格局為: HTTP/1.1 200 ok if (0 != pastLength) { // 內容規模字串 String contentRange = ""; // 呼應格局 // Content-Range: bytes [文件塊的開端字節]-[文件的總年夜小 - 1]||[文件的總年夜小] if (isFlashGet) { contentRange = new StringBuffer("bytes") .append(new Long(pastLength).toString()).append("-") .append(new Long(fileLength - 1).toString()) .append("/").append(new Long(fileLength).toString()) .toString(); } else { contentRange = new StringBuffer(rangeBytes).append("/") .append(new Long(fileLength).toString()).toString(); } response.setHeader("Content-Range", contentRange); } String fileName = getDownloadChineseFileName(filename); response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ""); // 呼應的格局是: response.setContentType("application/octet-stream"); response.addHeader("Content-Length", String.valueOf(fileLength)); try { os = response.getOutputStream(); outPut = new BufferedOutputStream(os); raf = new RandomAccessFile(downloadFile, "r"); // 跳過已下載字節 raf.seek(pastLength); if (isFlashGet) { // 慢車等 int n = 0; while ((n = raf.read(b, 0, 1024)) != -1) { outPut.write(b, 0, n); } } else { // 迅雷等 while (raf.getFilePointer() < lenEnd) { outPut.write(raf.read()); } } outPut.flush(); } catch (IOException e) { /** * 在寫數據的時刻 關於 ClientAbortException 之類的異常 * 是由於客戶端撤消了下載,而辦事器端持續向閱讀器寫入數據時, 拋出這個異常,這個是正常的。 特別是關於迅雷這類吸血的客戶端軟件。 * 明明曾經有一個線程在讀取 bytes=1275856879-1275877358, * 假如短時光內沒有讀取終了,迅雷會再啟第二個、第三個。。。線程來讀取雷同的字節段, 直到有一個線程讀取終了,迅雷會 KILL * 失落其他正鄙人載統一字節段的線程, 強行中斷字節讀出,形成辦事器拋 ClientAbortException。 * 所以,我們疏忽這類異常 */ } finally { if(outPut != null) { outPut.close(); } if(raf != null) { raf.close(); } } } private String getDownloadChineseFileName(String paramName) { String downloadChineseFileName = ""; try { downloadChineseFileName = new String(paramName.getBytes("GBK"), "ISO8859-1"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return downloadChineseFileName; } public String getFilepath() { return filepath; } public void setFilepath(String filepath) { this.filepath = filepath; } public String getFilename() { return filename; } public void setFilename(String filename) { this.filename = filename; } public HttpServletRequest getRequest() { return request; } public HttpServletResponse getResponse() { return response; }
2. struts部門
<action name="downloadFile" class="downloadFileAction" method="downloadFile">
<result name="failed" type="redirectAction">showDownloadFileNameList</result>
</action>
3. jsp部門
<td><a href="downloadFile?filename=${fileMap.key }&&filepath=${fileMap.value }">文件下載</a></td>