多线程断点续传

2017-03-06  本文已影响0人  HangChen

说明:
生成多个线程去服务器下载文件,服务器几乎同一时间处理每个线程,这样就会更快的下好文件,但注意并不是开的线程越多,速度越快。
文件的存储是有序的,必须保证下载的有序性,我们可以对需要下载的文件进行数据分块,这样每次访问的就可以不是完整的文件了。http协议有一个range字段,可以设置数据访问的区域位置,java中有RandomAccessfile类可以我们按需要去读写改某个区域。

代码:

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;

public class MutiDownload {
    private static String DOWNLOAD_PATH="http://s1.music.126.net/download/osx/NeteaseMusic_1.4.3_452_web.dmg";
    private static int THREAD_COUNT=3;
    private static final String fileName="/Users/August/Desktop/NeteaseMusic_1.4.3_452_web.dmg";
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        try {
            HttpURLConnection connection=(HttpURLConnection) new URL(DOWNLOAD_PATH).openConnection();
            //设置参数,发送GET请求
            connection.setRequestMethod("GET");
            //设置链接网络的超时时间
            connection.setConnectTimeout(8000);
            //获取返回码
            int code =connection.getResponseCode();
            if (code==200) {
                //代表请求成功
                RandomAccessFile raf=new RandomAccessFile(fileName, "rw");
                long filesize;
                filesize=connection.getContentLength();
                long eachsize = filesize/THREAD_COUNT;
                raf.setLength(filesize);
                raf.close();
                for (int i = 0; i < THREAD_COUNT; i++) {
                    long startIndex=i*eachsize;
                    long endIndex=(i+1)*eachsize;
                    if (i==THREAD_COUNT-1) {
                        endIndex=filesize-1;
                    }
                    //开启线程去服务器下载
                    DownloadThread downloadThread=new DownloadThread(DOWNLOAD_PATH,fileName,i,startIndex,endIndex);
                    
                }
            }else{
                
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally {
            
        }
        
        
        }
}
class DownloadThread extends Thread{
    private String url;
    private String fileName;
    private int threadId;
    private long startIndex;
    private long endIndex;
    private HttpURLConnection connection;
    private RandomAccessFile raf;
    private InputStream inputStream;
    public DownloadThread(String url,String fileName,int threadId,long startIndex,long endIndex) {
        this.endIndex=endIndex;
        this.fileName=fileName;
        this.startIndex=startIndex;
        this.threadId=threadId;
        this.url=url;
    }
    
    @Override
    public void run() {
        // TODO Auto-generated method stub
        
            try {
                 connection = (HttpURLConnection) new URL(url + "?ts=" + System.currentTimeMillis()).openConnection();
                connection.setRequestMethod("GET");
                connection.setConnectTimeout(8000);
                //告诉服务器每个线程的下载位置与结束位置
                connection.setRequestProperty("RANGE", "bytes=" + startIndex + "-" + endIndex);
                int code =connection.getResponseCode();
                if (code==206) {   //200代表请求全部资源成功,206代表请求部分资源成功
                     inputStream=connection.getInputStream();
                     raf=new RandomAccessFile(fileName, "rw");
                    raf.seek(startIndex);//
                    int len=-1;
                    long total=0;
                    byte[]buffer=new byte[1024];  //1kb
                    while ((len=inputStream.read(buffer))!=-1) {
                        total+=len;
                        System.out.println("线程"+threadId+":"+total);
                        raf.write(buffer,0,len);
                        
                    }
                }
            } catch (Exception e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            } finally {
                try{
                if (connection!=null) {
                    connection.disconnect();
                }
                if (raf!=null) {
                    raf.close();
                }
                if (inputStream!=null) {
                    inputStream.close();
                }
                }catch(Exception e2){
                    e2.printStackTrace();
                }
                
            }
    }
}
上一篇下一篇

猜你喜欢

热点阅读