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 }
  • 相关阅读:
    Session的使用与管理
    CSS控制文字,超出部分显示省略号
    MP4 文件前端获取视频封面
    prefetch预加载功能使用
    react-学习之路-react-router-解决问题记录
    如何将一个div盒子水平垂直都居中?
    window下查看端口号,并删除对应进程
    判断js 验证字符串里面有没有包含汉字:
    vue 现有的$变量 以及如何添加全局变量
    与人言
  • 原文地址:https://www.cnblogs.com/yoyohong/p/5889368.html
Copyright © 2011-2022 走看看