多线程下载 java_JAVA实现多线程下载

1.开启三个下载线程;

2.开启一个监视线程,用于查看下载进度。

7f2dae1d1853bed6a1332f5be935b4b4.png

完整代码

import java.io.InputStream;

import java.io.RandomAccessFile;

import java.net.HttpURLConnection;

import java.net.URL;

public class JavaMultiThreadDown {

public static void main(String[] args) throws Exception {

// 下载路径使用的是百度网盘上文件的下载路径

String _下载路径 = "https://bjbgp01.baidupcs.com/file/1d9cedae59e9042a85cb0b98b4340c9c?bkt=p3-00007b4ef6ea09a0f17a89712f670b4985c6&fid=3255250463-250528-363978972781448&time=1554510897&sign=FDTAXGERQBHSKfW-DCb740ccc5511e5e8fedcff06b081203-1Sm5YGIZMjBwhUyJY4n2UBJLkJ0%3D&to=75&size=5528379&sta_dx=5528379&sta_cs=0&sta_ft=pdf&sta_ct=0&sta_mt=0&fm2=MH%2CQingdao%2CAnywhere%2C%2Chubei%2Cpbs&ctime=1554510826&mtime=1554510826&resv0=cdnback&resv1=0&vuk=3255250463&iv=2&htype=&newver=1&newfm=1&secfm=1&flow_ver=3&pkey=00007b4ef6ea09a0f17a89712f670b4985c6&expires=8h&rt=sh&r=458234945&mlogid=2211612084113124362&vbdid=1929586120&fin=%E4%B8%8B%E8%BD%BD%E6%B5%8B%E8%AF%95.pdf&fn=%E4%B8%8B%E8%BD%BD%E6%B5%8B%E8%AF%95.pdf&rtype=1&dp-logid=2211612084113124362&dp-callid=0.1.1&hps=1&tsl=0&csl=0&csign=4j3EXxSQdY9W8SenN6CIXXqjvfE%3D&so=0&ut=1&uter=4&serv=0&uc=4192912830&ti=90e00819b6f54250603b4062c17fc35df0cc8c47b8fc9467&by=themis";

String _本地文件 = "有那种网站嘛?有,还是合集哦.pdf";

int _线程数量 = 3;

// 初始化DownUtil对象

final Downloader downLoader = new Downloader(_下载路径, _本地文件, _线程数量);

// 开始下载

downLoader.download();

}

}

class Downloader {

private String netUrl;// 下载资源的路径

private String saveFile;// 下载的路径(含文件名)

private int threadNum;// 线程数量

private DownLoaderThread[] threads;// 线程数组

private int fileSize;// 下载的文件的Size

public Downloader(String netUrl, String targetFile, int threadNum) {

this.netUrl = netUrl;

this.saveFile = targetFile;

this.threadNum = threadNum;

// 初始化线程数组

this.threads = new DownLoaderThread[threadNum];

}

public void download() throws Exception {

URL url = new URL(netUrl);

HttpURLConnection conn = (HttpURLConnection) url.openConnection();

conn.setConnectTimeout(5 * 1000);

conn.setRequestMethod("GET");

fileSize = conn.getContentLength();

System.out.println("待下载文件的大小为:" + (double) (fileSize / 1024) / 1024 + "M");

conn.disconnect();

// 分部下载

int currentPartSize = fileSize / threadNum + 1;

RandomAccessFile file = new RandomAccessFile(saveFile, "rw");

// 设置本地文件大小

file.setLength(fileSize);

file.close();

// 开启下载线程

for (int i = 0; i < threadNum; i++) {

// 计算每条线程的下载的开始位置

int startPos = i * currentPartSize;

// 每个线程使用一个RandomAccessFile进行下载

RandomAccessFile currentPart = new RandomAccessFile(saveFile, "rw");

// 定位线程的下载位置

currentPart.seek(startPos);

// 创建下载线程

threads[i] = new DownLoaderThread(startPos, currentPartSize, currentPart);

// 启动下载线程

threads[i].start();

}

Thread overseer = new Thread(new Overseer(this));

overseer.start();

}

private class DownLoaderThread extends Thread {

private int startPos;// 当前线程的下载位置

private int currentPartSize;// 当前线程负责下载的文件大小

private RandomAccessFile currentPart;// 当前线程需要下载的文件块

public int length;// 该线程已下载的字节数

public DownLoaderThread(int startPos, int currentPartSize, RandomAccessFile currentPart) {

this.startPos = startPos;

this.currentPartSize = currentPartSize;

this.currentPart = currentPart;

}

@Override

public void run() {

try {

URL url = new URL(netUrl);

HttpURLConnection conn = (HttpURLConnection) url.openConnection();

conn.setConnectTimeout(5 * 1000);

conn.setRequestMethod("GET");

InputStream inStream = conn.getInputStream();

// 跳过不需要下载的部分

inStream.skip(this.startPos);

byte[] buffer = new byte[1024];

int hasRead = 0;

// 读取网络数据,并写入本地文件

while (length < currentPartSize && (hasRead = inStream.read(buffer)) != -1) {

currentPart.write(buffer, 0, hasRead);

// 累计该线程下载的总大小

length += hasRead;

}

currentPart.close();

inStream.close();

} catch (Exception e) {

e.printStackTrace();

}

}

}

private class Overseer implements Runnable {

Downloader downLoader;

Overseer(Downloader downLoader) {

this.downLoader = downLoader;

}

@Override

public void run() {

double p;

while ((p = getCompleteRate()) < 100) {

// 隔段时间查询一次任务完成进度,

System.out.println("已完成:" + p + "%");

try {

Thread.sleep(1500);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

System.out.println("下载完毕");

}

// 获取下载的完成百分比

private double getCompleteRate() {

// 统计多条线程已经下载的总大小

int sumSize = 0;

for (int i = 0; i < threadNum; i++) {

sumSize += threads[i].length;

}

// 返回已经完成的百分比

int percent = (int) (sumSize * 100.0 / fileSize);

return percent;

}

}

}

运行结果

待下载文件的大小为:5.271484375M

已完成:0.0%

已完成:3.0%

已完成:13.0%

已完成:21.0%

已完成:29.0%

已完成:33.0%

已完成:35.0%

已完成:50.0%

已完成:64.0%

已完成:66.0%

已完成:66.0%

已完成:66.0%

已完成:66.0%

已完成:66.0%

已完成:73.0%

已完成:90.0%

下载完毕

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值