国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Java > 正文

java實現(xiàn)文件斷點續(xù)傳下載功能

2019-11-26 14:17:54
字體:
供稿:網(wǎng)友

本文實例為大家分享了java斷點續(xù)傳下載的代碼,供大家參考,具體內(nèi)容如下

1. Java代碼    

//實現(xiàn)文件下載功能  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;     // 用于記錄需要下載的結(jié)束字節(jié)數(shù)(迅雷或其他下載)     long lenEnd = 0;     // 用于記錄客戶端要求下載的數(shù)據(jù)范圍字串     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)       {      // 無結(jié)束字節(jié)數(shù),為快車      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());      // 還需下載的文件字節(jié)數(shù)(從已下載文件段開始)      lenEnd = Long.parseLong(endBytes);      }     }     // 通知客戶端允許斷點續(xù)傳,響應(yīng)格式為:Accept-Ranges: bytes     response.setHeader("Accept-Ranges", "bytes");     // response.reset();     // 如果為第一次下載,則狀態(tài)默認為 200,響應(yīng)格式為: HTTP/1.1 200 ok     if (0 != pastLength)     {      // 內(nèi)容范圍字串      String contentRange = "";      // 響應(yīng)格式      // Content-Range: bytes [文件塊的開始字節(jié)]-[文件的總大小 - 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 + "");     // 響應(yīng)的格式是:     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");      // 跳過已下載字節(jié)      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)     {      /**      * 在寫數(shù)據(jù)的時候 對于 ClientAbortException 之類的異常      * 是因為客戶端取消了下載,而服務(wù)器端繼續(xù)向瀏覽器寫入數(shù)據(jù)時, 拋出這個異常,這個是正常的。 尤其是對于迅雷這種吸血的客戶端軟件。      * 明明已經(jīng)有一個線程在讀取 bytes=1275856879-1275877358,      * 如果短時間內(nèi)沒有讀取完畢,迅雷會再啟第二個、第三個。。。線程來讀取相同的字節(jié)段, 直到有一個線程讀取完畢,迅雷會 KILL      * 掉其他正在下載同一字節(jié)段的線程, 強行中止字節(jié)讀出,造成服務(wù)器拋 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部分    

復(fù)制代碼 代碼如下:
<action name="downloadFile" class="downloadFileAction" method="downloadFile">
   <result name="failed" type="redirectAction">showDownloadFileNameList</result>
</action>

3. jsp部分    

復(fù)制代碼 代碼如下:
<td><a href="downloadFile?filename=${fileMap.key }&&filepath=${fileMap.value }">文件下載</a></td>

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 石门县| 台江县| 马鞍山市| 临汾市| 德安县| 新乐市| 西乌珠穆沁旗| 伊宁市| 佛教| 竹山县| 渑池县| 阳城县| 化隆| 精河县| 寿光市| 黔西县| 富顺县| 吉木萨尔县| 泽州县| 望奎县| 冷水江市| 包头市| 平顶山市| 称多县| 镶黄旗| 离岛区| 水富县| 湄潭县| 郸城县| 安溪县| 牙克石市| 裕民县| 浦北县| 茌平县| 新竹市| 广安市| 潼关县| 凤阳县| 嘉鱼县| 嘉鱼县| 突泉县|