欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

 更新時(shí)間:2016年05月24日 16:16:25   作者:鐘志誠(chéng)  
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)文件斷點(diǎn)續(xù)傳下載功能的具體代碼,感興趣的小伙伴們可以參考一下

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

1. Java代碼    

//實(shí)現(xiàn)文件下載功能
  public String downloadFile(){
    File dir = new File(filepath);//獲取文件路勁
    if(!dir.exists()) {
      System.out.println("文件路徑錯(cuò)誤");
      log.debug("文件路徑錯(cuò)誤");
      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");
     //用于隨機(jī)讀取寫入文件
     RandomAccessFile raf = null;
     OutputStream os = null;
     OutputStream outPut = null;
     byte b[] = new byte[1024];
     // 如果客戶端下載請(qǐng)求中包含了范圍
     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);
      }
     }
     // 通知客戶端允許斷點(diǎn)續(xù)傳,響應(yīng)格式為:Accept-Ranges: bytes
     response.setHeader("Accept-Ranges", "bytes");
     // response.reset();
     // 如果為第一次下載,則狀態(tài)默認(rèn)為 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ù)的時(shí)候 對(duì)于 ClientAbortException 之類的異常
      * 是因?yàn)榭蛻舳巳∠讼螺d,而服務(wù)器端繼續(xù)向?yàn)g覽器寫入數(shù)據(jù)時(shí), 拋出這個(gè)異常,這個(gè)是正常的。 尤其是對(duì)于迅雷這種吸血的客戶端軟件。
      * 明明已經(jīng)有一個(gè)線程在讀取 bytes=1275856879-1275877358,
      * 如果短時(shí)間內(nèi)沒有讀取完畢,迅雷會(huì)再啟第二個(gè)、第三個(gè)。。。線程來讀取相同的字節(jié)段, 直到有一個(gè)線程讀取完畢,迅雷會(huì) KILL
      * 掉其他正在下載同一字節(jié)段的線程, 強(qiáng)行中止字節(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>

相關(guān)文章

  • 關(guān)于Spring?Ioc和DI注解的問題

    關(guān)于Spring?Ioc和DI注解的問題

    這篇文章主要介紹了Spring?Ioc和DI注解,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-03-03
  • Java實(shí)現(xiàn)的簡(jiǎn)單數(shù)字處理類及用法示例

    Java實(shí)現(xiàn)的簡(jiǎn)單數(shù)字處理類及用法示例

    這篇文章主要介紹了Java實(shí)現(xiàn)的簡(jiǎn)單數(shù)字處理類及用法,涉及java數(shù)字運(yùn)算相關(guān)操作技巧,需要的朋友可以參考下
    2018-01-01
  • mybatis typeAliases 給實(shí)體類起別名的方法

    mybatis typeAliases 給實(shí)體類起別名的方法

    這篇文章主要介紹了mybatis typeAliases 給實(shí)體類起別名,本文給大家分享兩種用法,通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-09-09
  • 詳談java中boolean和Boolean的區(qū)別

    詳談java中boolean和Boolean的區(qū)別

    下面小編就為大家?guī)硪黄斦刯ava中boolean和Boolean的區(qū)別。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-03-03
  • SpringBatch數(shù)據(jù)寫入實(shí)現(xiàn)

    SpringBatch數(shù)據(jù)寫入實(shí)現(xiàn)

    Spring Batch通過ItemWriter接口及其豐富的實(shí)現(xiàn),提供了強(qiáng)大的數(shù)據(jù)寫入能力,本文主要介紹了SpringBatch數(shù)據(jù)寫入實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下
    2025-04-04
  • 新手初學(xué)Java常見排序算法

    新手初學(xué)Java常見排序算法

    排序(Sorting) 是計(jì)算機(jī)程序設(shè)計(jì)中的一種重要操作,它的功能是將一個(gè)數(shù)據(jù)元素(或記錄)的任意序列,重新排列成一個(gè)關(guān)鍵字有序的序列
    2021-07-07
  • Java中枚舉的使用詳解

    Java中枚舉的使用詳解

    這篇文章主要介紹了Java中枚舉的使用詳解的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-07-07
  • Filter、Servlet、Listener的學(xué)習(xí)_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    Filter、Servlet、Listener的學(xué)習(xí)_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    這篇文章主要為大家詳細(xì)介紹了Filter、Servlet、Listener的學(xué)習(xí)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • Java并發(fā)編程學(xué)習(xí)之Unsafe類與LockSupport類源碼詳析

    Java并發(fā)編程學(xué)習(xí)之Unsafe類與LockSupport類源碼詳析

    這篇文章主要給大家介紹了關(guān)于Java并發(fā)編程學(xué)習(xí)之Unsafe類與LockSupport類源碼的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起看看吧
    2018-06-06
  • springboot大文件上傳、分片上傳、斷點(diǎn)續(xù)傳、秒傳的實(shí)現(xiàn)

    springboot大文件上傳、分片上傳、斷點(diǎn)續(xù)傳、秒傳的實(shí)現(xiàn)

    本文主要介紹了springboot大文件上傳、分片上傳、斷點(diǎn)續(xù)傳、秒傳的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07

最新評(píng)論