zoukankan      html  css  js  c++  java
  • HttpURLConnection 多线程下载

     


    影响下载的速度

    * 宽带的带宽

    * 服务器的限制

    * 服务器的资源固定,开启的线程越多抢占的资源就越多

    import java.io.InputStream;
    
    import java.io.RandomAccessFile;
    
    import java.net.HttpURLConnection;
    
    import java.net.URL;
    
    public class MultiDownLoad {
    
       static String path = http://192.168.3.100:8080/web/download/gui.exe;
       static int threadCount = 3;
    
       /**
        * 获取文件的存储路径
        */
    
       static String getFilePath(){
    
          int index = path.lastIndexOf("/")+1;
    
          return "D:\"+path.substring(index);
    
       }
       public static void main(String[] args) {
    
          try {
             // 1. 在客户端创建和服务器资源一样大小的空文件
    
             URL url = new URL(path);
    
             HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    
             conn.setConnectTimeout(3000);
    
             conn.setRequestMethod("GET");
    
             int code = conn.getResponseCode();
    
             //服务器资源文件的大小
    
             int fileLength = 0;
    
             if (code == 200) {
    
                fileLength = conn.getContentLength();
    
                System.out.println("文件大小:"+fileLength);
            
    //          //可选,可以不写,检测硬盘的空间够不够用
    
    //          RandomAccessFile raf = new RandomAccessFile(getFilePath(), "rw");
    
    //          //在硬盘上创建控件
    
    //          raf.setLength(fileLength);
    
    //          raf.close();
    
             }
    
             //每个线程下载的区块大小
    
             int blockSize  = fileLength / threadCount;
          
             // 2. 客户端开启多个线程去下载服务器的资源
    
             for (int threadId = 0; threadId < threadCount; threadId++) {
    
                int startIndex = threadId * blockSize;
    
                int endIndex = (threadId + 1)* blockSize -1;
    
                //最后一个线程,修正下载的结束位置
    
                if (threadId == threadCount-1) {
    
                    endIndex = fileLength - 1;
    
                }
               
                //开启线程
    
                new DownLoadThread(startIndex, endIndex, threadId).start();
    
             }
    
          } catch (Exception e) {
    
             e.printStackTrace();
    
          }
    
       }
       
       static class DownLoadThread extends Thread {
    
          //开始位置
    
          int startIndex;
    
          //结束位置
    
          int endIndex;
    
          //线程ID
    
          int threadId;
    
          public DownLoadThread(int startIndex, int endIndex, int threadId) {
    
             super();
    
             this.startIndex = startIndex;
    
             this.endIndex = endIndex;
    
             this.threadId = threadId;
    
          }
    
          @Override
    
          public void run() {
    
             super.run();
    
             System.out.println("线程 : "+  threadId + " : "+ startIndex+" ~ "+endIndex);
    
             try {
    
                URL url = new URL(path);
    
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    
                conn.setRequestMethod("GET");
    
                conn.setConnectTimeout(3000);
    
                //重要,设置请求的范围
    
                conn.setRequestProperty("Range", "bytes="+startIndex+"-"+endIndex);
    
                //部分请求成功 206
    
                int code = conn.getResponseCode();
    
                System.out.println(" code = "+code);
    
                if (code == 206) {
    
                    RandomAccessFile raf = new RandomAccessFile(getFilePath(), "rw");
    
                    //重要,写文件之前定位
    
                    raf.seek(startIndex);
                 
                    //获取这个线程对应的一块资源
    
                    InputStream is = conn.getInputStream();
    
                    byte[] buffer = new byte[1024*8];
    
                    int len = -1;
                  
                    while((len = is.read(buffer)) != -1){
                     
                       raf.write(buffer, 0, len);
    
                    }
                  
                    raf.close();
                }
             
                // 3. 每个线程都下载完毕,整个资源就下载完了
    
                System.out.println("线程 "+threadId+" 干完活了!");
    
             } catch (Exception e) {
    
                e.printStackTrace();
    
             }
    
          }
    
       }
    
    }
    
  • 相关阅读:
    在xp中用sc命令安装自己写的服务的具体步骤
    .net中导出excel数据不全的解决方案
    转载:20092010年中国商业智能市场分析
    xp发布多维数据集过程
    .net中导出excel时不能自动显示网格线的解决方案
    .net中访问多维数据集报错
    在xp中用DOS添加服务时,输入SC命令提示不可用的解决方案
    jenkins在奴隶机上安装dotnetsdk
    .NET Core 使用jenkins发布代码
    jenkins添加linux方法
  • 原文地址:https://www.cnblogs.com/loaderman/p/6432469.html
Copyright © 2011-2022 走看看