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


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

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

    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);

  • 相关阅读:
    简析Java RMI 与 .NET Remoting
    实现一个压缩Remoting传输数据的Sink:CompressionSink (转载)
    智能部署与更新
    第二章:.NET Remoting基础知识
    创建以Microsoft .NET Remoting为基础的分布式应用架构
    vs2005如何防止代码被反编译
    使用.NET Remoting开发分布式应用——配置文件篇(转载)
    Remoting概述
    高级 .NET Remoting
    第一章:Remoting技术简介
  • 原文地址:https://www.cnblogs.com/yysbolg/p/10484381.html
Copyright © 2020-2023  润新知