package core;
import constant.Constant;
import util.FileUtils;
import util.HttpUtils;
import util.LogUtils;
import java.io.*;
import java.net.HttpURLConnection;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.concurrent.*;
/**
* 下载器类
* Created by Lenovo
* DATA:2023/10/19
**/
public class Downloader {
private ScheduledExecutorService scheduledExecutorService= Executors.newScheduledThreadPool(1);
//线程池对象
public ThreadPoolExecutor poolExecutor=new ThreadPoolExecutor(Constant.THREAD_NUM,Constant.THREAD_NUM,0,TimeUnit.SECONDS,new ArrayBlockingQueue<>(5));
public void download(String url) throws IOException {
//获取文件的名字
String httpFileName = HttpUtils.getHtpFileName(url);//从文件的下载路径中截取。
// 文件的下载路径
httpFileName= Constant.PATH+httpFileName;//就是我设置的本地的下载文件夹的名字加上下载文件的名字。
//获取本地文件的大小。
long localFileLength= FileUtils.getFileContextLength(httpFileName);
// 获取链接对象
HttpURLConnection httpURLConnection=null;
DownloadInfoThread downloadInfoThread=null;
try{
httpURLConnection = HttpUtils.getHttpURLConnection(url);
//获取下载文件的总大小
int contextLength=httpURLConnection.getContentLength();
//判断文件是是不是已经下载过了。
if(localFileLength>=contextLength){
LogUtils.info("{}文件已经下载过了",httpFileName);
return;
}
//创建获取下载信息的任务对象。
downloadInfoThread = new DownloadInfoThread(contextLength);
//件任务交给线程执行,每隔一秒执行一次。
scheduledExecutorService.scheduleAtFixedRate(downloadInfoThread,1,1, TimeUnit.SECONDS);
//切分任务
ArrayList<Future> futureArrayList = new ArrayList<>();
split(url,futureArrayList);
for (Future future : futureArrayList) {
try {
future.get();
} catch (InterruptedException e) {
throw new RuntimeException(e);
} catch (ExecutionException e) {
throw new RuntimeException(e);
}
}
//合并文件:
if(merge(httpFileName)){
clearTemp(httpFileName);
}
}finally {
System.out.print("下载完成。");
if(httpURLConnection!=null){
httpURLConnection.disconnect();//关闭连接对象。
}
scheduledExecutorService.shutdownNow();//关闭
poolExecutor.shutdown();//关闭线程池
}
}
public void split(String url, ArrayList<Future> futureArrayList) throws IOException {
//获取下载文件的大小。
try{
long httpFileContentLength = HttpUtils.getHttpFileContentLength(url);
//计算切分后的文件大小。
long size=httpFileContentLength/Constant.THREAD_NUM;
//计算分块个数。
for(int i=0;i<Constant.THREAD_NUM;i++){
long startPos=i*size;//计算下载的起始位置
long endPos;//计算结束位置
if(i==Constant.THREAD_NUM-1){
//下载最后一块,下载剩余的部分。
endPos=0;
}else{
endPos=startPos+size;
}
//如果不是第一块,起始位置要+1;
if(startPos!=0){
startPos++;
}
//创建任务。
DownloaderTask downloaderTask = new DownloaderTask(url, startPos, endPos, i);
// 将任务提交到线程池中
Future<Boolean> submit = poolExecutor.submit(downloaderTask);
futureArrayList.add(submit);
}
}catch (IOException e){
e.printStackTrace();
}
}
/**
* 合并代码
*/
public boolean merge(String fileName) {
LogUtils.info("开始合并文件{}", fileName);
byte[] bytes = new byte[Constant.BYTE_SIZE];
int len = -1;
try (RandomAccessFile randomAccessFile = new RandomAccessFile(fileName, "rw")) {
for (int i = 0; i < Constant.THREAD_NUM; i++) {
try(BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(fileName+".temp"+i))){
while ((len = bufferedInputStream.read(bytes)) != -1) {
randomAccessFile.write(bytes, 0, len);
}
}
}
LogUtils.info("文件合成完毕{}"+fileName);
}catch (Exception e){
e.printStackTrace();
return false;
}
return false;
}
/**
* 清除文件。
* @param fileName
* @return
*/
public boolean clearTemp(String fileName){
for (int i = 0; i <Constant.THREAD_NUM ; i++) {
new File(fileName+".temp"+i).delete();
}
return true;
}
}
没有合适的资源?快使用搜索试试~ 我知道了~
使用Java多线程来实现对文件的下载(文件切割下载)
共27个文件
java:11个
class:9个
xml:3个
需积分: 1 0 下载量 76 浏览量
2023-11-29
13:55:30
上传
评论 1
收藏 27KB ZIP 举报
温馨提示
Java多线程是指在一个Java程序中同时运行多个任务的能力。这些任务可以并发执行,从而提高程序的效率。Java多线程的优点包括提高程序的响应性、增强用户体验以及提高程序的可移植性。然而,多线程也可能会导致程序变得复杂和变慢。在Java中,多线程通常通过创建多个线程来实现,并且每个线程可以独立地执行特定的任务。 在Java中,创建多线程有几种方法: 1. 继承Thread类:Java中的Thread类是实现多线程的最基本方法。你可以通过继承Thread类并重写其run()方法来创建自己的线程。然后,你可以创建线程的实例,并调用start()方法启动线程。 2. 实现Runnable接口:如果你不想继承Thread类,你可以实现Runnable接口。Runnable接口只有一个需要实现的方法run(),你可以在run()方法中编写线程的代码。然后,你可以将实现了Runnable接口的对象传递给Thread类的构造方法来创建线程。 3. 使用Executor框架:Java中的Executor框架提供了一种更高级的方式来创建和管理线程。你可以使用Executors类创建不同类型的Execut
资源推荐
资源详情
资源评论
收起资源包目录
java-multithreaded-downloader-master.zip (27个子文件)
java-multithreaded-downloader-master
src
constant
Constant.java 284B
learn
PoolTest02.java 386B
PoolTest01.java 862B
ScheduleTest.java 1KB
core
DownloaderTask.java 2KB
Downloader.java 5KB
DownloadInfoThread.java 2KB
Main.java 820B
util
LogUtils.java 755B
HttpUtils.java 3KB
FileUtils.java 416B
out
production
demo
constant
Constant.class 448B
learn
PoolTest01.class 2KB
ScheduleTest.class 2KB
Main.class 1KB
core
DownloadInfoThread.class 2KB
Downloader.class 6KB
util
FileUtils.class 616B
HttpUtils.class 3KB
LogUtils.class 2KB
demo.iml 423B
.idea
vcs.xml 180B
misc.xml 271B
modules.xml 248B
.gitignore 176B
sonarlint
issuestore
index.pb 0B
securityhotspotstore
index.pb 0B
共 27 条
- 1
资源评论
crmeb专业二开
- 粉丝: 569
- 资源: 181
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功