`

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

 

实例代码如下:

/**
	 * 下载服务器已存在的文件
	 * 
	 * @param request
	 * @param response
	 * @param proposeFile
	 * @throws IOException
	 * @throws FileNotFoundException
	 */
	private void downloadExistsFile(HttpServletRequest request,
			HttpServletResponse response, File proposeFile) throws IOException,
			FileNotFoundException {
		log.debug("下载文件路径:" + proposeFile.getPath());
		long fSize = proposeFile.length();
		// 下载
		response.setContentType("application/x-download");
		String isoFileName = this
				.encodeFilename(proposeFile.getName(), request);
		response.setHeader("Accept-Ranges", "bytes");
		response.setHeader("Content-Length", String.valueOf(fSize));
		response.setHeader("Content-Disposition", "attachment; filename="
				+ isoFileName);
		long pos = 0;
		if (null != request.getHeader("Range")) {
			// 断点续传
			response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
			try {
				pos = Long.parseLong(request.getHeader("Range").replaceAll(
						"bytes=", "").replaceAll("-", ""));
			} catch (NumberFormatException e) {
				log.error(request.getHeader("Range") + " is not Number!");
				pos = 0;
			}
		}
		ServletOutputStream out = response.getOutputStream();
		BufferedOutputStream bufferOut = new BufferedOutputStream(out);
		InputStream inputStream = new FileInputStream(proposeFile);
		String contentRange = new StringBuffer("bytes ").append(
				new Long(pos).toString()).append("-").append(
				new Long(fSize - 1).toString()).append("/").append(
				new Long(fSize).toString()).toString();
		response.setHeader("Content-Range", contentRange);
		log.debug("Content-Range", contentRange);
		inputStream.skip(pos);
		byte[] buffer = new byte[5 * 1024];
		int length = 0;
		while ((length = inputStream.read(buffer, 0, buffer.length)) != -1) {
			bufferOut.write(buffer, 0, length);
		}
		bufferOut.flush();
		bufferOut.close();
		out.close();
		inputStream.close();
	}

 

 

 

分享到:
评论
3 楼 sfg1314 2015-09-28  
暂停后重新下载就会报错:ClientAbortException:  java.io.IOException
2 楼 sfg1314 2015-09-28  
暂停后重新下载报错啊
1 楼 aliahhqcheng 2013-07-26  
soga

相关推荐

Global site tag (gtag.js) - Google Analytics