java多线程下载

package cn.itcast.download;

import java.io.File;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;
/***
 * 多线程下载类:
 * 一般的所有断点下载工具都会在下载开始生成两个文件:
 *   一个是与网络资源大小相同的空文件,一个是配置文件,
 *   该配置文件分别记录每个线程已经下载到了哪个字节,当网络断开后再次下载时,
 *   每个线程根据配置文件里记录的位置向后下载即可。
 * 未实现:进度条、断点下载、线程池管理
 * @author huawei
 *
 */
public class MulThreadDownload {
 //入口
 public static void main(String[] args)  throws Exception {
  String path = "http://192.168.1.102:8080/web/AndroidAPI.chm";
  new MulThreadDownload().download(path, 3);
 }
 
 private void download(String path, int threadsize) throws Exception {
  URL url = new URL(path);
  HttpURLConnection conn = (HttpURLConnection) url.openConnection();
  conn.setConnectTimeout(5000);
  conn.setRequestMethod("GET");

  if(conn.getResponseCode() == 200){
   //取得待下载文件的长度:用于给每个线程分配下载量
   int length = conn.getContentLength();
   File file = new File(getFileName(path));
   //主要操作文件类型为:"rwd",即及时写入
   RandomAccessFile accessFile = new RandomAccessFile(file, "rwd");
   //将文件设置和待下载文件一样的长度大小的空间
   accessFile.setLength(length);
   accessFile.close();

   //计算每条线程负责下载数据量
   int block = length % threadsize == 0 ?length/threadsize : length/threadsize + 1;
   //创建线程
   for(int threadid = 0;threadid < threadsize; threadid++){
    new DownloadThread(threadid, block, url, file).start();
   }
  }else{
   System.out.println("下载链接失败");
  }
 }
 //线程:
 private class DownloadThread extends Thread{
  private int threadid;
  private int block;
  private URL url;
  private File file;
  public DownloadThread(int threadid, int block, URL url, File file) {
   this.threadid = threadid;
   this.block = block;
   this.url = url;
   this.file = file;
  }

  public void run() {
   //取得当前线程开始下载的位置
   int start = threadid * block;
   //取得当前线程结束下载的位置
   int end = (threadid + 1) * block - 1;
   System.out.println(start+"--"+end);
   try {
    RandomAccessFile accessFile = new RandomAccessFile(file, "rwd");
    //将游标移动到每个线程的开始处
    accessFile.seek(start);
    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    conn.setConnectTimeout(5000);
    conn.setRequestMethod("GET");
    //设置向web请求下载的区间:http下载支持Range属性
    conn.setRequestProperty("Range", "bytes=" + start +"-" + end);
    //注意:分区间下载的返回码为206
    if(conn.getResponseCode() == 206){
     InputStream in = conn.getInputStream();
     byte[] buffer = new byte[1024];
     int len = 0;
     while((len = in.read(buffer)) != -1){
      accessFile.write(buffer, 0, len);
     }
     in.close();
    }
    accessFile.close();
    System.out.println("线程"+ (threadid + 1) +"下载完成");
   } catch (Exception e) {
    e.printStackTrace();
   }
  }
 }
 //获取保存文件名
 private String getFileName(String path) {
  
  return path.substring(path.lastIndexOf("/") + 1);
 }
}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值