Java Web 文件下载之断点续传

        断点续传,听上去似乎是个比较高级的话题,本文只讲述一下http版的断点续传,其他协议的大家可以自行研究。

        http协议中,服务端实现断点续传首先需要读取客户端传送的Range头信息,比如“Range: bytes=12583394-这个就是指原来正在下载的文件需要从第12583394字节继续下载,然后我们利用java.io.File的skip方法,舍弃掉原文件的前n个字节,接着就继续慢慢write吧。。。

       但是客户端又是如何判断服务端是否支持断点续传的呢?主要就是Accept-Ranges和Content-Length头信息。比如“Accept-Ranges:bytes”和“Content-Length:99999999”。有了这两个头信息,客户端就认为服务端是支持断点续传的了。

       然后需要注意的是,假如客户端刚才由于某些原因,暂停了下载,现在恢复的时候,就会如前所述,传来Range头信息,这时候,我们的response就需要设置一下状态码,这里应该设置成206(详细解释请看http://en.wikipedia.org/wiki/List_of_HTTP_status_codes),还有就是Content-Range头信息,格式为“bytes x-(y-1)/y”,x就是客户端传来的开始字节位置,y就是文件长度。

(以上转自:http://blog.csdn.net/xiaoxiaoxuewen/article/details/7701170

 

实例代码如下:

Java代码   收藏代码
  1. /** 
  2.      * 下载服务器已存在的文件 
  3.      *  
  4.      * @param request 
  5.      * @param response 
  6.      * @param proposeFile 
  7.      * @throws IOException 
  8.      * @throws FileNotFoundException 
  9.      */  
  10.     private void downloadExistsFile(HttpServletRequest request,  
  11.             HttpServletResponse response, File proposeFile) throws IOException,  
  12.             FileNotFoundException {  
  13.         log.debug("下载文件路径:" + proposeFile.getPath());  
  14.         long fSize = proposeFile.length();  
  15.         // 下载  
  16.         response.setContentType("application/x-download");  
  17.         String isoFileName = this  
  18.                 .encodeFilename(proposeFile.getName(), request);  
  19.         response.setHeader("Accept-Ranges""bytes");  
  20.         response.setHeader("Content-Length", String.valueOf(fSize));  
  21.         response.setHeader("Content-Disposition""attachment; filename="  
  22.                 + isoFileName);  
  23.         long pos = 0;  
  24.         if (null != request.getHeader("Range")) {  
  25.             // 断点续传  
  26.             response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);  
  27.             try {  
  28.                 pos = Long.parseLong(request.getHeader("Range").replaceAll(  
  29.                         "bytes=""").replaceAll("-"""));  
  30.             } catch (NumberFormatException e) {  
  31.                 log.error(request.getHeader("Range") + " is not Number!");  
  32.                 pos = 0;  
  33.             }  
  34.         }  
  35.         ServletOutputStream out = response.getOutputStream();  
  36.         BufferedOutputStream bufferOut = new BufferedOutputStream(out);  
  37.         InputStream inputStream = new FileInputStream(proposeFile);  
  38.         String contentRange = new StringBuffer("bytes ").append(  
  39.                 new Long(pos).toString()).append("-").append(  
  40.                 new Long(fSize - 1).toString()).append("/").append(  
  41.                 new Long(fSize).toString()).toString();  
  42.         response.setHeader("Content-Range", contentRange);  
  43.         log.debug("Content-Range", contentRange);  
  44.         inputStream.skip(pos);  
  45.         byte[] buffer = new byte[5 * 1024];  
  46.         int length = 0;  
  47.         while ((length = inputStream.read(buffer, 0, buffer.length)) != -1) {  
  48.             bufferOut.write(buffer, 0, length);  
  49.         }  
  50.         bufferOut.flush();  
  51.         bufferOut.close();  
  52.         out.close();  
  53.         inputStream.close();  
  54.     }  
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值