多线程断点下载

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

  • 具体代码体现

/**
 * 多线程断点下载
 * @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("文件下载完毕,清楚记录");
                    }
                }
            }
        }
    }
}

你可能感兴趣的:(多线程断点下载)