当前位置: 移动技术网 > IT编程>开发语言>Java > 视频图片--多线程下载工具

视频图片--多线程下载工具

2019年03月07日  | 移动技术网IT编程  | 我要评论

还嫌网速慢? 那是因为你没有一个好的下载工具, 多线程下载, 线程个数自己定义, 想多块就多快,一起来看看吧!!!

多线程使用线程计数同步辅助,同步计算多线程个数,如果线程下载超时, 支持重新下载,方便使用.

 

 

 

 

1.多线程工具类:   mutithreaddownload.java

 

import java.io.inputstream;
import java.io.randomaccessfile;
import java.net.httpurlconnection;
import java.net.url;
import java.text.simpledateformat;
import java.util.date;
import java.util.concurrent.countdownlatch;

public class mutithreaddownload {
    // 同时下载的线程数
    private int threadcount;
    // 服务器请求路径
    private string serverpath;
    //记录下载完成的次数
    public static int number_thread=50;
    //本地路径
    private string localpath;
    //线程计数同步辅助
    private countdownlatch latch;
 
    public mutithreaddownload(int threadcount, string serverpath, string localpath, countdownlatch latch) {
        this.number_thread=threadcount;
        this.threadcount = threadcount;
        this.serverpath = serverpath;
        this.localpath = localpath;
        this.latch = latch;
    }

 
    public boolean executedownload() {
        try {
            url url = new url(serverpath);
            httpurlconnection conn = (httpurlconnection) url.openconnection();
            conn.setconnecttimeout(5000);
            conn.setrequestmethod("get");
            int code = conn.getresponsecode();
            if (code == 200) {
                //服务器返回的数据的长度,实际上就是文件的长度,单位是字节
                int length = conn.getcontentlength();
                system.out.println("文件总长度:" + length + "字节(b)");
                if (length == 0) {
                    return false;
                }

                randomaccessfile raf = new randomaccessfile(localpath, "rwd");
                //指定创建的文件的长度
                raf.setlength(length);
                raf.close();
                //分割文件
                int blocksize = length / threadcount;
                for (int threadid = 1; threadid <= threadcount; threadid++) {
                    //第一个线程下载的开始位置
                    int startindex = (threadid - 1) * blocksize;
                    int endindex = startindex + blocksize - 1;
                    if (threadid == threadcount) {
                        //最后一个线程下载的长度稍微长一点
                        endindex = length;
                    }

                    system.out.println("线程" + threadid + "下载:" + startindex + "字节~" + endindex + "字节");
                    new downloadthread(threadid, startindex, endindex).start();
                }
            }
        } catch (exception e) {
            e.printstacktrace();
        }
      return true;
    }


    /**

     * 内部类用于实现下载

     */

    public class downloadthread extends thread {
        //线程id
        private int threadid;
        //下载起始位置
        private int startindex;
        //下载结束位置
        private int endindex;

        public downloadthread(int threadid, int startindex, int endindex) {
            this.threadid = threadid;
            this.startindex = startindex;
            this.endindex = endindex;
        }

        @override
        public void run() {
            down_time();
        }

 

        /**

         * 如果超时,或者下载失败,就使用递归重新下载

         */

        public void down_time(){
            try {
                system.out.println("线程" + threadid + "正在下载...");
                url url = new url(serverpath);
                httpurlconnection conn = (httpurlconnection) url.openconnection();
                conn.setrequestmethod("get");
                //请求服务器下载部分的文件的指定位置
                conn.setrequestproperty("range", "bytes=" + startindex + "-" + endindex);
                conn.setconnecttimeout(10000);
                conn.setreadtimeout(10000);
                int code = conn.getresponsecode();
                system.out.println("线程" + threadid + "请求返回code=" + code);
                inputstream is = conn.getinputstream();//返回资源
                randomaccessfile raf = new randomaccessfile(localpath, "rwd");
                //随机写文件的时候从哪个位置开始写
                raf.seek(startindex);//定位文件
                int len = 0;
                byte[] buffer = new byte[1024];
                while ((len = is.read(buffer)) != -1) {
                    raf.write(buffer, 0, len);
                }
                is.close();
                raf.close();
                number_thread=number_thread-1;
                system.out.println("线程" + threadid + "下载完毕  "+number_thread);
                //计数值减一
                latch.countdown();
            } catch (exception e) {
                system.out.println(new simpledateformat("yyyy-mm-dd hh:mm:ss aa").format(new date())+":线程 "+threadid + "访问超时,重新下载!!");
                down_time();
            }
        }
    }
}

 

 

 

2.封装工具类方法:

   public static boolean download(string remoteurl,string localurl){
    boolean bd=true;
    int threadsize = 50;
    string serverpath = remoteurl;
    string localpath = localurl;
    long starttime = system.currenttimemillis();
    countdownlatch latch = new countdownlatch(threadsize);
    mutithreaddownload m = new mutithreaddownload(threadsize, serverpath, localpath, latch);
    try {
        boolean x = m.executedownload();
        //如果文件的长度等于0,则直接跳过等待,不提示错误
        if (x){
            latch.await();
        }else{
            bd=false;//下载失败
        }
    } catch (interruptedexception e) {
        e.printstacktrace();
    }

    long endtime = system.currenttimemillis();
    system.out.println("全部下载结束,共耗时" + (endtime - starttime) / 1000 + "s");
    return bd;
}

 

 

3.使用示例:

string urlss="";//要下载的网络资源路径

string urltt="";//要存放的本地路径

download(urlss,urltt);

 

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网