程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> java完成文件斷點續傳下載功效

java完成文件斷點續傳下載功效

編輯:關於JAVA

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>

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved