0%

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;
    }
}