实现多线程下载同一个文件

论坛 期权论坛 脚本     
匿名技术用户   2021-1-3 00:57   11   0
原理:

示例代码:
public class LoadFile {

 private static int threadCount = 3;// 下载的线程数量

 public static void main(String[] args) {
  
  // 1、与服务器建立连接,获得文件的大小,在本地创建一个与需下载文件同等大小的临时文件
  String path = "http://localhost/safe.exe";
  try {
   URL url = new URL(path);
   HttpURLConnection conn = (HttpURLConnection) url.openConnection();
   conn.setRequestMethod("GET");
   conn.setReadTimeout(5000);
   
   int code = conn.getResponseCode();
   if(200 == code) {
    // 获得文件的长度
    int length = conn.getContentLength();
    System.out.println("文件总长度为:"+length);
    // 在本地创建一个可以随机读取的与源文件同等大小的临时文件
    RandomAccessFile raf = new RandomAccessFile("safe.exe", "rwd");
    // 指定文件的长度
    raf.setLength(length);// 设置文件长度
    raf.close();
    
    // 2、实现多线程下载资源
    int blockSize = length / threadCount ;// 每个线程平均需要下载文件的大小
    for(int threadId = 1; threadId <= threadCount; threadId++) {
     // 每个线程下载文件的初始位置和结束位置
     int startIndex = (threadId-1) * blockSize;
     int endIndex = threadId * blockSize - 1;
     // 下载的最后一块的情况
     if(threadCount == threadId) {
      endIndex = length - 1;// 如果不减1的话,就超出了文件的范围
     }
     System.out.println("线程 "+threadId+"下载位置为:"+startIndex+"--->"+endIndex);
     // 启动下载线程
     new DownloadThread(path, startIndex, endIndex, threadId).start();
    }
    
   } else {
    System.out.println("服务器出现错误");
   }
   
  } catch (Exception e) {
   System.out.println("连接服务器URL出现错误");
   e.printStackTrace();
  }
  
 }

}

public class DownloadThread extends Thread {

 private String path;// 服务器路径
 private int startIndex;// 块文件开始位置
 private int endIndex;// 快文件结束位置
 private int threadId;// 线程编号

 public DownloadThread() {

 }

 public DownloadThread(String path, int startIndex, int endIndex, int threadId) {
  this.path = path;
  this.startIndex = startIndex;
  this.endIndex = endIndex;
  this.threadId = threadId;
 }

 @Override
 public void run() {
  try {
   URL url = new URL(path);
   HttpURLConnection conn = (HttpURLConnection) url.openConnection();
   conn.setRequestMethod("GET");
   conn.setReadTimeout(5000);
   // 提交请求可以从指定位置读取文件
   conn.setRequestProperty("Range", "bytes=" + startIndex + "-"
     + endIndex);
   int code = conn.getResponseCode();
   // 请求全部文件成功返回200, 请求部分文件成功返回206
   if (206 == code) {
    RandomAccessFile raf = new RandomAccessFile("safe.exe", "rwd");
    // 随机文件从哪里读
    raf.seek(startIndex);// 定位文件

    InputStream is = conn.getInputStream();
    int len = 0;
    byte[] buffer = new byte[1024];
    while ((len = is.read(buffer)) != -1) {
     raf.write(buffer, 0, len);
    }
    
    is.close();
    raf.close();
    System.out.println("线程" + threadId + "下载完毕!!!!");
   } else {
    System.out.println("线程"+threadId+"请求的部分资源失败");
   }

  } catch (Exception e) {
   System.out.println("下载线程的URL连接异常");
   e.printStackTrace();
  }
 }

}
// 别下载太大的文件,可能等待时间很长
/*Output:
文件总长度为:11556608
线程 1下载位置为:0--->3852201
线程 2下载位置为:3852202--->7704403
线程 3下载位置为:7704404--->11556607
线程2下载完毕!!!!
线程1下载完毕!!!!
线程3下载完毕!!!!
*/



分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:7942463
帖子:1588486
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP