美文网首页
多线程断点下载

多线程断点下载

作者: 蛋蛋不哭 | 来源:发表于2016-05-21 13:10 被阅读103次

    根据多线程下载,我们知道,当我们在下载的时候如果遇到断电或者损坏,我们要从以前记录的数据文件接着下载,这样的下载就是多线程断点下载,,

    • 具体代码体现

    /**
     * 多线程断点下载
     * @author dandan
     *
     */
    public class Demo {
    
        public static int threadCount = 3;
        private static int runningthread = 3;
        //链接服务器,获取服务器端文件,得到文件长度,在本地创建一个和服务器端大小相同的文件
        public static void main(String[] args) throws Exception{
    
            String path = "http://100.77.34.45:8686/360.exe";
            URL url = new URL(path);
            HttpURLConnection conn = (HttpURLConnection) url.getContent();
            conn.setReadTimeout(5000);
            conn.setRequestMethod("GET");
            int code = conn.getResponseCode();
            if(code == 200){
                //得到服务器端文件的长度
                int length = conn.getContentLength();
                System.out.println("文件总长度: "+length);
                //在客户端创建一个临时文件 
                RandomAccessFile raf = new RandomAccessFile("steup.exe", "rwd");
                //大小和服务器端文件大小一致
                raf.setLength(length);
                raf.close();
                //利用多线程进行下载
                //平均每个线程下载的文件大小
                int blocksize = length/threadCount;
                for(int threadid=1;threadid<=threadCount;threadid++){
                    //线程开始的位置
                    int startid = (threadid-1)*blocksize;
                    //线程结束的位置
                    int endid = threadid*blocksize-1;
                    if(threadid==threadCount){
                        endid=length;
                    }
                    System.out.println("线程真实的大小: "+threadid+"下载: ----"+startid+"---->"+endid);
                    //主线程开启子线程
                    new downloadthread(threadid, startid, endid, path).start();
                }
            }
            else {
                System.out.println("服务器错误");
            }
        }
        //下载文件的子线程 下载对应位置的文件
        public static class downloadthread extends Thread{
            private int threadid;
            private int startid;
            private int endid;
            private String path;
            /**
             * @param threadid 线程id
             * @param startid 线程开始的位置
             * @param endid 线程结束的位置
             * @param path 访问服务器的路径
             */
            public downloadthread(int threadid, int startid, int endid, String path) {
                super();
                this.threadid = threadid;
                this.startid = startid;
                this.endid = endid;
                this.path = path;
            }
    
            @Override
            public void run() {
                URL url;
                try {
                    //检查是否存在记录下载长度的文件,如果存在读取这个文件数据
                    //判断一下是否有断点存在,且不为空
                    File tempFile = new File(threadid+".txt");
                    if(tempFile.exists()&&tempFile.length()>0){
                        FileInputStream fis = new FileInputStream(tempFile);
                        byte[] temp = new byte[1024];
                        int leng = fis.read(temp);
                        String downloadlen = new String(temp,0,leng);
                        //吧downloadlen转换成Int类型
                        int downloadint = Integer.parseInt(downloadlen);
                        startid+=downloadint;//修改下载的真实的开始位置
                        fis.close();
                    }
                    
                    url = new URL(path);
                    HttpURLConnection conn = (HttpURLConnection) url.getContent();
                    conn.setReadTimeout(5000);
                    conn.setRequestProperty("Range", "bytes= "+startid+"--"+endid);
                    conn.setRequestMethod("GET");
                    int code = conn.getResponseCode();//200 ok 代表请求全部数据      //206 ok 代表请求部分数据
                    InputStream is = conn.getInputStream(); 
                    RandomAccessFile raf = new RandomAccessFile("steup.exe", "rwd");
                    //随机写文件从哪个位置开始写,定位文件位置
                    raf.seek(startid);
                    int len = 0;
                    int total = 0;//已经下载的文件长度
                    byte[] buffer = new byte[1024];
                    
                    while((len = is.read(buffer))!=-1){
                        RandomAccessFile file = new RandomAccessFile(threadid+".txt", "rwd");
                        //吧获取到的is流写到raf里面去
                        raf.write(buffer, 0, len);
                        total+=len;
                        file.write((""+total+startid).getBytes());
                        file.close();
                    }
                    is.close();
                    raf.close();
                    System.out.println("多线程下载完成: "+threadid);
                    
                    File deletefile = new File(threadid+".txt");
                    deletefile.delete();//下载完成后  清楚下载记录
                } catch (Exception e) {
                    e.printStackTrace();
                }
                finally{
                    //每个线程下载完毕以后,runningthread进行--操作
                    runningthread--;
                    if(runningthread==0){
                        for(int i=0;i<3;i++){
                            File file = new File(i+".txt");
                            file.delete();
                            System.out.println("文件下载完毕,清楚记录");
                        }
                    }
                }
            }
        }
    }
    
    

    相关文章

      网友评论

          本文标题:多线程断点下载

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