zoukankan      html  css  js  c++  java
  • 使用多线程去下载同一个文件

     1 import java.io.InputStream;
     2 import java.io.RandomAccessFile;
     3 import java.net.HttpURLConnection;
     4 import java.net.URL;
     5 
     6 public class Demo {
     7     public static String path = "<a target="_blank" href="http://softdownload.hao123.com/hao123-soft-online-bcs/soft/Y/2013-07-18_YoudaoDict_baidu.alading.exe">http://softdownload.hao123.com/hao123-soft-online-bcs/soft/Y/2013-07-18_YoudaoDict_baidu.alading.exe</a>";
     8     public static int threadCount = 3;
     9     public static void main(String[] args) throws Exception{
    10         //1.连接服务器,获取一个文件,获取文件的长度,在本地创建一个跟服务器一样大小的临时文件
    11         URL url = new URL(path);
    12         HttpURLConnection conn = (HttpURLConnection)url.openConnection();
    13         conn.setConnectTimeout(5000);
    14         conn.setRequestMethod("GET");
    15         int code = conn.getResponseCode();
    16         if (code == 200) {
    17             //服务器端返回的数据的长度,实际上就是文件的长度
    18             int length = conn.getContentLength();
    19             System.out.println("文件总长度:"+length);
    20             //在客户端本地创建出来一个大小跟服务器端一样大小的临时文件
    21             RandomAccessFile raf = new RandomAccessFile("setup.exe", "rwd");
    22             //指定创建的这个文件的长度
    23             raf.setLength(length);
    24             raf.close();
    25             //假设是3个线程去下载资源。
    26             //平均每一个线程下载的文件大小.
    27             int blockSize = length / threadCount;
    28             for (int threadId = 1; threadId <= threadCount; threadId++) {
    29                 //第一个线程下载的开始位置
    30                 int startIndex = (threadId - 1) * blockSize;
    31                 int endIndex = threadId * blockSize - 1;
    32                 if (threadId == threadCount) {//最后一个线程下载的长度要稍微长一点
    33                     endIndex = length;
    34                 }
    35                 System.out.println("线程:"+threadId+"下载:---"+startIndex+"--->"+endIndex);
    36                 new DownLoadThread(path, threadId, startIndex, endIndex).start();
    37             }
    38         
    39         }else {
    40             System.out.printf("服务器错误!");
    41         }
    42     }
    43     
    44     /**
    45      * 下载文件的子线程  每一个线程下载对应位置的文件
    46      * @author jie
    47      *
    48      */
    49     public static class DownLoadThread extends Thread{
    50         private int threadId;
    51         private int startIndex;
    52         private int endIndex;
    53         /**
    54          * @param path 下载文件在服务器上的路径
    55          * @param threadId 线程Id
    56          * @param startIndex 线程下载的开始位置
    57          * @param endIndex    线程下载的结束位置
    58          */
    59         public DownLoadThread(String path, int threadId, int startIndex, int endIndex) {
    60             super();
    61             this.threadId = threadId;
    62             this.startIndex = startIndex;
    63             this.endIndex = endIndex;
    64         }
    65 
    66         @Override
    67         public void run() {
    68             try {
    69                 URL url = new URL(path);
    70                 HttpURLConnection conn = (HttpURLConnection)url.openConnection();
    71                 conn.setConnectTimeout(5000);
    72                 conn.setRequestMethod("GET");
    73                 //重要:请求服务器下载部分文件 指定文件的位置
    74                 conn.setRequestProperty("Range", "bytes="+startIndex+"-"+endIndex);
    75                 //从服务器请求全部资源返回200 ok如果从服务器请求部分资源 返回 206 ok
    76                 int code = conn.getResponseCode();
    77                 System.out.println("code:"+code);
    78                 InputStream is = conn.getInputStream();//已经设置了请求的位置,返回的是当前位置对应的文件的输入流
    79                 RandomAccessFile raf = new RandomAccessFile("setup.exe", "rwd");
    80                 //随机写文件的时候从哪个位置开始写
    81                 raf.seek(startIndex);//定位文件
    82             
    83                 int len = 0;
    84                 byte[] buffer = new byte[1024];
    85                 while ((len = is.read(buffer)) != -1) {
    86                     raf.write(buffer, 0, len);
    87                 }
    88                 is.close();
    89                 raf.close();
    90                 System.out.println("线程:"+threadId+"下载完毕");
    91             } catch (Exception e) {
    92                 e.printStackTrace();
    93             }
    94         }
    95         
    96     }
    97 }
  • 相关阅读:
    sparql学习sparql示例、dbpedia在线验证
    中国绿卡
    逾期率的水有多深,你知道吗?
    ICO和区块链区别
    What are the benefits to using anonymous functions instead of named functions for callbacks and parameters in JavaScript event code?
    Link static data in sql source control
    sql data compare
    viewbag
    多态的实际使用
    win10 sedlauncher.exe占用cpu处理
  • 原文地址:https://www.cnblogs.com/yoyohong/p/5889368.html
Copyright © 2011-2022 走看看