• 多线程下载文件,以及断点下载


    一:前言

    多线程下载文件,可能有的同学没有过多的听说过,但是断点下载肯定是听过的,也就是说像讯雷,哪怕你把电脑重启了,讯雷重新启动后也会接着原来的地方下载,那么这是怎么做到的呢?

    二:代码示例

    直接给出代码,

    2.1、经典代码

    两行经典的代码分别为:

    //设置下载的开始及结束位置
    conn.setRequestProperty("Range", "bytes="+start+"-"+end+"");
    //设置读写的起点位置
    RandomAccessFile raf = new RandomAccessFile("e:/test/temp.exe","rw");
    raf.seek(start);

    2.2、完整代码:

    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.URL;
    import java.util.Date;
    
    public class Demo {
        /**
         * 下载线程数量<br>
         * 我用5个线程下载用了37秒,用1个线程下载用了45秒
         */
        private static int num = 5;
    
        public static void main(String[] args) {
            threadDown();
        }
    
        public final static void threadDown() {
            try {
                URL url = new URL("http://dldir1.qq.com/qqfile/qq/QQ8.2/17724/QQ8.2.exe");
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                int size = conn.getContentLength();
                // 每个纯种下载该大小
                int block = size / num;
    
                // 这个类支持对于文件的随机访问,第一个参数是文件名,第二个是访问模式,rw代表读写
                RandomAccessFile raf = new RandomAccessFile("e:/test/temp.exe","rw");
                // 在本地创建一个空文件,大小与服务器的文件保持一致
                raf.setLength(size);
                raf.close();
    
                // 定义一个开始下载的位置,结束下载的位置
                int start;
                int end;
                for (int i = 0; i < num; i++) {
                    start = i * block;
                    if (num == i + 1) {
                        end = size;
                    } else {
                        end = block * (i + 1);
                    }
                    System.out.println("开始:" + start + ", 结束:" + end);
                    ThreadDown down = new ThreadDown(start,end);
                    down.start();
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    class ThreadDown extends Thread{
        private int start;
        private int end;
        public ThreadDown(int start,int end){
            this.start = start;
            this.end = end;
        }
        public void run() {
            long startTime = new Date().getTime();
            String name = Thread.currentThread().getName();
            try {
                System.out.println(name + ":启动");
                URL url = new URL("http://dldir1.qq.com/qqfile/qq/QQ8.2/17724/QQ8.2.exe");
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                //这里也是重点,设置了请求的开始字节与结束字节
                conn.setRequestProperty("Range", "bytes="+start+"-"+end+"");
                InputStream in = conn.getInputStream();
                
                RandomAccessFile raf = new RandomAccessFile("e:/test/temp.exe","rw");
                //设置读写的起点位置,这里是重点
                raf.seek(start);
                byte[] buf = new byte[1024];
                int len = 0;
                while((len=in.read(buf))!= -1){
                    raf.write(buf, 0, len);
                }
                
                in.close();
                raf.close();
                long endTime = new Date().getTime();
                long useTime = (endTime - startTime) / 1000;
                System.out.println(name + "下载完成,共耗时:" + useTime + "秒");
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
    
        }
        
    }

    三:断点下载

    想来看过了上面的代码,断点下载的原理大家肯定也是知道了,同样的也是采用

    //设置下载的开始及结束位置
    conn.setRequestProperty("Range", "bytes="+start+"-"+end+"");
    //设置读写的起点位置
    RandomAccessFile raf = new RandomAccessFile("e:/test/temp.exe","rw");
    raf.seek(start);

     

  • 相关阅读:
    浅入浅出EmguCv(一)OpenCv与EmguCv
    Selenium2入门(三)WebDriver API之Get
    Selenium2入门(二)WebDriver
    Selenium2入门(一)简介
    Tomcat部署Solr4.10.4
    On the Optimal Approach of Survivable Virtual Network Embedding in Virtualized SDN
    几篇虚拟映射文章粗读
    SDN网络虚拟化中有效协调的映射算法
    SDN网络中hypervisor带来的控制器时延(Hypervisor位置的优化)
    FlowerVisor理解
  • 原文地址:https://www.cnblogs.com/zhuxiaojie/p/5384970.html
Copyright © 2020-2023  润新知