美文网首页
多线程断点续传

多线程断点续传

作者: HangChen | 来源:发表于2017-03-06 17:44 被阅读0次

    说明:
    生成多个线程去服务器下载文件,服务器几乎同一时间处理每个线程,这样就会更快的下好文件,但注意并不是开的线程越多,速度越快。
    文件的存储是有序的,必须保证下载的有序性,我们可以对需要下载的文件进行数据分块,这样每次访问的就可以不是完整的文件了。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();
                    }
                    
                }
        }
    }
    

    相关文章

      网友评论

          本文标题:多线程断点续传

          本文链接:https://www.haomeiwen.com/subject/beyugttx.html