发布于 2016-07-10 15:55:24 | 72 次阅读 | 评论: 0 | 来源: 网友投递

这里有新鲜出炉的Java设计模式,程序狗速度看过来!

Java程序设计语言

java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由Sun Microsystems公司于1995年5月推出的Java程序设计语言和Java平台(即JavaEE(j2ee), JavaME(j2me), JavaSE(j2se))的总称。


这篇文章主要为大家详细介绍了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>



相关阅读 :
java实现文件断点续传下载功能
Java如何实现HTTP断点续传功能
java基于servlet编写上传下载功能 类似文件服务器
JAVA实现FTP断点上传的方法
java实现文件复制上传操作
java文件上传下载功能实现代码
java中struts2实现文件上传下载功能
java中struts2实现文件上传下载功能实例解析
java断点续传功能实例(java获取远程文件)
JavaWeb中struts2实现文件上传下载功能实例解析
JavaEE中struts2实现文件上传下载功能实例解析
Java编程实现服务器端支持断点续传的方法(可支持快车、迅雷)
最新网友评论  共有(0)条评论 发布评论 返回顶部
月排行榜

Copyright © 2007-2017 PHPERZ.COM All Rights Reserved   冀ICP备14009818号  版权声明  广告服务