Java下载断点续传(下载优酷视频实例)

断点续传的关键在于发送RANGE值,以及建立随机访问文件对象,跳到文件末尾。
下面的代码是断线续传下载优酷的视频。测试方法:运行后,会循环输出当前下载的进度,在下载完之前强行停止(Eclipse上的红色Stop按钮),重新运行,可以看到续传效果。


package com.download;

import java.io.File;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;

public class Main {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		final String url = "http://f.youku.com/player/getFlvPath/sid/130586142897819_01/st/flv/fileid/03000202004DD41099B25204CFA0FDD01CCF75-CE87-989C-6950-ED1081070F59?K=b52bd8f2ccfb40d6161bacc0&hd=0";
		final String path = "c://1.flv";
		final long filesize;
		RemoteFile rf=getRemoteFile(url);
		long remoteSize=rf.size;
		final String realUrl=rf.realUrl;
		//得到重定向后的真实URL,经测试,优酷视频,如果不用真实URL下载,会报403错误
		System.out.println("真实URL"+realUrl);
		System.out.println("远程文件大小" + remoteSize);
		File f = new File(path);
		if (f.exists()) {
			filesize = f.length();
		} else {
			filesize = 0;
		}
		System.out.println("本地文件长度" + filesize);
		if (filesize < remoteSize) {
			new Thread() {
				public void run() {
					try {
						System.out.println("开始下载");
						URL u = new URL(realUrl);
						HttpURLConnection connection = (HttpURLConnection) u
								.openConnection();
						connection.setRequestProperty("RANGE", "bytes="+ filesize+"-");
						//根据已下载的大小,设置下载的起点
						connection.setRequestProperty("User-Agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.1.4322)"); 
						//设置UA
						InputStream input = connection.getInputStream();
						//读入InputStream
						RandomAccessFile SavedFile = new RandomAccessFile(path, "rw");
						//建立随机访问对象
						SavedFile.seek(filesize);
						//文件指针移动到文件末尾
						byte[] b = new byte[1024];
						//新建byte对象
						int nRead;
						long readed=filesize;
						//readed用于存储已下载的字节数,所以初始值为文件大小
						while ((nRead = input.read(b, 0, 1024)) > 0) {
							//从InputStream循环读入byte对象,nRead为实际读入的byte对象长度
							readed+=nRead;
							//已下载长度计数
							System.out.println(readed);
							SavedFile.write(b, 0, nRead);
							//把byte对象写入文件
						}
						connection.disconnect();
						//断开连接
						SavedFile.close();
						//关闭文件
					} catch (Exception e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}.start();
		}
	}

	public static RemoteFile getRemoteFile(String url) {
		long size = 0;
		String realUrl="";
		try {
			HttpURLConnection conn = (HttpURLConnection) (new URL(url))
					.openConnection();
			size = conn.getContentLength();
			//远程文件体积
			realUrl=conn.getURL().toString();
			//真实URL
			conn.disconnect();
		} catch (Exception e) {
			e.printStackTrace();
		}
		RemoteFile rf=new RemoteFile(size,realUrl);
		//把取得的文件体积及真实URL返回
		return rf;
	}

}
class RemoteFile{
	//RemoteFile类,用于存储远程文件的大小及重定向后的地址
	long size;
	String realUrl;
	RemoteFile(long size,String realUrl){
		this.size=size;
		this.realUrl=realUrl;
	}
}

© 2011, 冰冻鱼. 请尊重作者劳动成果,复制转载保留本站链接! 应用开发笔记