`
samttsch
  • 浏览: 62931 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

JAVA断点续传简单实现

阅读更多
断点续传主要是使用http协议中range的属性来取得资源的部分内容,由于一般服务是不对外直接提供url访问的,一般都是通过id,在servlet中输出byte[]来实现,所以要想实现断点续传一般要自己实现一个服务端。

一个简单实现:
服务端:主要是分析了range属性,利用RandomAccessFile读取内容输出字节流
public class Download extends HttpServlet {

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {

		int id = Integer.parseInt(req.getParameter("id"));
		String filename ;
		if (id == 1)
			filename = "E:/JDK_API_1_5_zh_CN.CHM";
		else if (id == 2)
			filename = "E;/JDK_API_1_6_zh_CN.CHM";
		else if (id == 3)
			filename = "E:/apache-tomcat-5.5.26/webapps/ROOT/tomcat.gif";
		else
			filename = "c.rar";

		RandomAccessFile raFile = new RandomAccessFile(filename, "r");
		
		String range = req.getHeader("RANGE");
		int start=0, end=0;
		if(null!=range && range.startsWith("bytes=")){
			String[] values =range.split("=")[1].split("-");
			start = Integer.parseInt(values[0]);
			end = Integer.parseInt(values[1]);
		}
		int requestSize=0;
		if(end!=0 && end > start){
			requestSize = end - start + 1;
			resp.addHeader("content-length", ""+(requestSize));
		} else {
			requestSize = Integer.MAX_VALUE;
		}
		
		byte[] buffer = new byte[4096];
		
		resp.setContentType("application/x-download");
		resp.addHeader("Content-Disposition", "attachment;filename=a.chm");
		ServletOutputStream os = resp.getOutputStream();
		
		int needSize = requestSize;
		
		raFile.seek(start);
		while(needSize > 0){
			int len = raFile.read(buffer);
			if(needSize < buffer.length){
				os.write(buffer,0,needSize);
			} else {
				os.write(buffer,0,len);
				if(len < buffer.length){
					break;
				}
			}
			needSize -= buffer.length;
		}
			
		raFile.close();
		os.close();
	}
}



客户端:分两次取得部分内容,输出到RandomAccessFile中
public static void main(String[] args) throws MalformedURLException, FileNotFoundException {
		test1(0,1000);
		test1(1001,0);
	}
	
	public static void test1(int start, int end) throws MalformedURLException, FileNotFoundException{
		
		String endpoint = "http://localhost:8080/Hello/download?id=1";
		
		RandomAccessFile raFile = new RandomAccessFile("E:/temp/test.chm", "rw");
		
		URL url = new URL(endpoint);
		try {
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			//conn.addRequestProperty("location", "/tomcat.gif");
			conn.setRequestProperty("Content-Type","text/html; charset=UTF-8"); 
			conn.setRequestProperty("RANGE","bytes="+start+"-"+end); 
			
			conn.connect();
			System.out.println(conn.getResponseCode());
			System.out.println(conn.getContentLength());
			System.out.println(conn.getContentType());
			
			InputStream ins = (InputStream)conn.getContent();
			
			raFile.seek(start);
			
			byte[] buffer = new byte[4096];
			int len = -1;
			while((len = ins.read(buffer))!=-1){
				raFile.write(buffer,0,len);
			}
			raFile.close();
			conn.disconnect();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}


接下来的工作:实现客户端的并发,多线程,即多个下载任务同时进行,连接的复用,实现暂停,显示进度条,下载完成的事件处理等,不涉及具体业务,搭建整个架构。
分享到:
评论
1 楼 xujianjie12138 2015-09-18  
大赞!谢谢你!

相关推荐

Global site tag (gtag.js) - Google Analytics