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>

(0)

相关推荐

  • Java编程实现服务器端支持断点续传的方法(可支持快车、迅雷)

    本文实例讲述了Java编程实现服务器端支持断点续传的方法.分享给大家供大家参考,具体如下: 大家知道Tomcat之流对静态资源可以实现断点续传支持,但是如果是一个被控制的流,如有权限控制,或下载地址仅是个代理的时候,这时候需要自己实现断点续传的支持,小弟不才,这里提供基本断点续传[a-,-b,a-b]的简单实现,经验证,可支持迅雷7和火狐的多次断点续传.现贴出代码,大家共同分享: Servlet import java.io.BufferedOutputStream; import java.i

  • 命令行使用支持断点续传的java多线程下载器

    复制代码 代码如下: package org.load.download; import java.io.File;import java.io.IOException;import java.io.InputStream;import java.io.RandomAccessFile;import java.text.DecimalFormat; import org.apache.http.HttpEntity;import org.apache.http.HttpResponse;impo

  • java断点续传功能实例(java获取远程文件)

    复制代码 代码如下: import java.io.BufferedInputStream; import java.io.DataOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.RandomAccessFile; import java.net . * ; /** * 文件传送客户端:获取远程文件 */ public cl

  • 很简单的Java断点续传实现原理

    原理解析 在开发当中,"断点续传"这种功能很实用和常见,听上去也是比较有"逼格"的感觉.所以通常我们都有兴趣去研究研究这种功能是如何实现的? 以Java来说,网络上也能找到不少关于实现类似功能的资料.但是呢,大多数都是举个Demo然后贴出源码,真正对其实现原理有详细的说明很少. 于是我们在最初接触的时候,很可能就是直接Crtl + C/V代码,然后捣鼓捣鼓,然而最终也能把效果弄出来.但初学时这样做其实很显然是有好有坏的. 好处在于,源码很多,解释很少:如果我们肯下功

  • Java实现的断点续传功能的示例代码

    代码中已经加入了注释,需要的朋友可以直接参考代码中的注释.下面直接上功能实现的主要代码: import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.RandomAccessFile; import java.net.HttpURLConnection; import java.net.Malfor

  • Java如何实现HTTP断点续传功能

    (一)断点续传的原理 其实断点续传的原理很简单,就是在Http的请求上和一般的下载有所不同而已. 打个比方,浏览器请求服务器上的一个文时,所发出的请求如下: 假设服务器域名为wwww.sjtu.edu.cn,文件名为down.zip. GET /down.zip HTTP/1.1 Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms- excel, application/msword, a

  • java实现文件断点续传下载功能

    本文实例为大家分享了java断点续传下载的代码,供大家参考,具体内容如下 1. Java代码     //实现文件下载功能 public String downloadFile(){ File dir = new File(filepath);//获取文件路劲 if(!dir.exists()) { System.out.println("文件路径错误"); log.debug("文件路径错误"); return "failed";// 判断文件

  • 通过Java实现文件断点续传功能

    目录 什么是断点续传 解决方案 效果演示 参考代码 前端 后端 什么是断点续传 用户上传大文件,网络差点的需要历时数小时,万一线路中断,不具备断点续传的服务器就只能从头重传,而断点续传就是,允许用户从上传断线的地方继续传送,这样大大减少了用户的烦恼. 解决上传大文件服务器内存不够的问题 解决如果因为其他因素导致上传终止的问题,并且刷新浏览器后仍然能够续传,重启浏览器(关闭浏览器后再打开)仍然能够继续上传,重启电脑后仍然能够上传 检测上传过程中因网络波动导致文件出现了内容丢失那么需要自动检测并且从

  • java多文件压缩下载的解决方法

    Java多文件压缩下载解决方案,供大家参考,具体内容如下 需求: 会员运营平台经过改版后页面增加了许多全部下载链接,上周上线比较仓促,全部下载是一个直接下载ZIP压缩文件的链接,每个ZIP压缩文件都是由公司运营人员将页面需要下载的文件全部压缩成一个ZIP压缩文件,然后通过公司的交易运营平台上传至文件资料系统,会员运营平台则可以直接获取ZIP压缩文件地址进行下载 下面是一个页面示例: 需求分析: 通过上面需求和页面可以分析出,公司运营人员将页面全部需要下载的文件进行ZIP压缩后上传文件资料系统确实

  • php实现大文件断点续传下载实例代码

    php实现大文件断点续传下载实例,看完你就知道超过100M以上的大文件如何断点传输了,这个功能还是比较经典实用的,毕竟大文件上传功能经常用得到. require_once('download.class.php'); date_default_timezone_set('Asia/Shanghai'); error_reporting(E_STRICT); function errorHandler($errno, $errstr, $errfile, $errline) { echo '<p>

  • Java多线程文件分片下载实现的示例代码

    多线程下载介绍 多线程下载技术是很常见的一种下载方案,这种方式充分利用了多线程的优势,在同一时间段内通过多个线程发起下载请求,将需要下载的数据分割成多个部分,每一个线程只负责下载其中一个部分,然后将下载后的数据组装成完整的数据文件,这样便大大加快了下载效率.常见的下载器,迅雷,QQ旋风等都采用了这种技术. 分片下载 所谓分片下载就是要利用多线程的优势,将要下载的文件一块一块的分配到各个线程中去下载,这样就极大的提高了下载速度. 技术难点 并不能说是什么难点,只能说没接触过不知道罢了. 1.如何请

  • ztree+ajax实现文件树下载功能

    基于java实现文件树下载,供大家参考,具体内容如下 0.项目准备工作 1.前端用到的插件库: ztree官网 2.后端maven依赖: <dependencies> <!-- servlet依赖 --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0&

  • JavaWeb 实现多个文件压缩下载功能

    文件下载时,我们可能需要一次下载多个文件.批量下载文件时,需要将多个文件打包为zip,然后再下载. 实现思路有两种: 一是将所有文件先打包压缩为一个文件,然后下载这个压缩包, 二是一边压缩一边下载,将多个文件逐一写入到压缩文件中.我这里实现了边压缩边下载. 下载样式: 点击下载按钮,会弹出下载框: 下载后就有一个包含刚刚选中的两个文件: 代码实现: FileBean public class FileBean implements Serializable { private Integer f

  • C#实现文件断点续传下载的方法

    本文实例讲述了C#实现文件断点续传下载的方法.分享给大家供大家参考.具体实现方法如下: using System; using System.Data; using System.Configuration; using System.Web; using System.Web.Security; using System.IO; using System.Text; using System.Net; namespace simpleDemo { class Program { /// <su

  • java压缩文件和下载图片示例

    本文实例为大家分享了java压缩文件和下载图片示例,供大家参考,具体内容如下 主页面index.xml <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <html> <head> <title>项目的主页</title> </head> <body> <h2>主页

  • Android多线程断点续传下载功能实现代码

    原理 其实断点续传的原理很简单,从字面上理解,所谓断点续传就是从停止的地方重新下载. 断点:线程停止的位置. 续传:从停止的位置重新下载. 用代码解析就是: 断点:当前线程已经下载完成的数据长度. 续传:向服务器请求上次线程停止位置之后的数据. 原理知道了,功能实现起来也简单.每当线程停止时就把已下载的数据长度写入记录文件,当重新下载时,从记录文件读取已经下载了的长度.而这个长度就是所需要的断点. 续传的实现也简单,可以通过设置网络请求参数,请求服务器从指定的位置开始读取数据. 而要实现这两个功

随机推荐