`

一个支持断点续传、多线程下载的servlet的实现(JavaWeb、JSP)

    博客分类:
  • Java
阅读更多
直接上源码


Servlet源码

protected void service(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		//获取文件URI
		String path = URLDecoder.decode(request.getRequestURI().replace(
				getServletContext().getContextPath() + "/download", ""),"UTF-8");
		//获取文件
		File file = (File) ManualBuffer.get(path);
		if (file == null) {
			DirectoryTree dt = DirectoryTree.getInstance();
			file = dt.findByPath(path);
			if (file == null) {
				response.sendError(404);
				return;
			}
			ManualBuffer.put(path, file);
		}
		//文件名
		String filename=file.getFilename();
		//获取文件读取对象
		FileReader fr=file.getReader();
		//获取浏览器类型
		String browser=request.getHeader("user-agent");
		// 设置响应头,206支持断点续传
		int http_status=206;
		if(browser.contains("MSIE"))
			http_status=200;//200 响应头,不支持断点续传
		response.reset();
		response.setStatus(http_status);
		//响应头
		response.setContentType("application/octet-stream;charset=UTF-8");
		try {
			//下载起始位置
			long since=0;
			//下载结束位置
			long until=file.getSize()-1;
			//获取Range,下载范围
			String range=request.getHeader("range");
			if(range!=null){
				//剖解range
				range=range.split("=")[1];
				String[] rs=range.split("-");
				if(AuthFilter.isDigit(rs[0])){
					since=Integer.parseInt(rs[0]);
				}
				if(rs.length>1&&AuthFilter.isDigit(rs[1])){
					until=Integer.parseInt(rs[1]);
				}
			}
			//设置响应头
			response.setHeader("Accept-Ranges", "bytes");
			response.setHeader("Content-Range", "bytes "+since+"-"+ until + "/"
					+ file.getSize());
			//文件名用ISO08859_1编码
			response.setHeader("Content-Disposition", "attachment; filename=\"" +
					new String(filename.getBytes(),"ISO8859_1")+ "\"");
			response.setHeader("Content-Length", "" + (until-since+1));
			System.out.println("download: "+filename);
			//定位到请求位置
			fr.seek(since);
			byte[] buffer=new byte[128*1024];
			int len;
			boolean full=false;
			//读取,输出流
			while((len=fr.read(buffer))>0){
				if(fr.tell()-1>until){
					len=(int) (len-(fr.tell()-until-1));
					full=true;
				}
				response.getOutputStream().write(buffer, 0, len);
				if(full)
					break;
			}
			//输出
			response.getOutputStream().flush();
			response.getOutputStream().close();
		} catch (java.net.SocketException e) {
			//连接断开
		}finally{
			if(fr!=null)
				fr.close();
		}
		response.flushBuffer();
	}


FileReader接口
public interface FileReader {

	/**
	 * 移动文件指针到指定位置
	 * @param pos
	 * @throws IOException
	 */
	public void seek(long pos) throws IOException;

	/**
	 * 获取文件指针位置
	 * @return 文件指针位置
	 * @throws IOException
	 */
	public long tell() throws IOException;

	/**
	 * 从文件指针开始读取一段数据到数组中,返回读取的字节数
	 * @param byte数组
	 * @return 读取的字节数
	 * @throws IOException
	 */
	public int read(byte[] bytes) throws IOException;

	/**
	 * 从文件指针开始读取一段数据到数组指定位置中,返回读取的字节数
	 * @param byte数组
	 * @param off数组偏移量
	 * @param len读取的最大字节数
	 * @return 读取的字节数
	 * @throws IOException
	 */
	public int read(byte[] bytes, int off, int len) throws IOException;
	
	/**
	 * 关闭
	 */
	public void close();
}
分享到:
评论
2 楼 小蜗牛狂奔 2015-04-30  
qq123zhz 写道
有没有完整一点的

1 楼 qq123zhz 2012-01-09  
有没有完整一点的

相关推荐

Global site tag (gtag.js) - Google Analytics