java 多线程实现下载文件
---自己记录
多线程下载文件
-
使用调取
`public class methodTest {
public static String filePath="\deme.zip"; //文件保存地址
public static String fileUrl="https://download.java.net/java/GA/jdk19/877d6127e982470ba2a7faa31cc93d04/36/GPL/openjdk-19_windows-x64_bin.zip";//文件地址public static void main(String[] args) {
System.out.println("开始");
//查看文件在不在
UseThread useThread = new UseThread();
useThread.downFile(filePath,fileUrl); //filePath:本地保存地点+文件名 fileUrl:线上文件地址System.out.println("结束");
}
}` -
下载文件
`@Slf4j
public class UseThread {
//调用线程
//限制线程数量
private int threadNum = 3;public void downFile(String localPath,String onlinePath){
int fileLength = 0 ; //要下载文件的长度
//首先链接Url
try {
//获取链接
URL url = new URL(onlinePath);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
int responseCode = conn.getResponseCode();
//链接成功?
if( responseCode == 200 ){
//获取文件大小,多线程 指针位置不同需要提前设置
fileLength = conn.getContentLength();
//判断 本地是否存在
File file = new File(localPath);if( !file.exists() ){
//本地文件不存在,创建
file.createNewFile();
}
//随机访问文件,设置本地文件长度
RandomAccessFile raf = new RandomAccessFile(localPath,"rwd");
raf.setLength(fileLength);//每个线程需要下载的长度
int blockSize = fileLength/threadNum;for( int i = 0 ; i < threadNum ; i++){
//计算每个文件开始-结束下载放入位置
int startSize = iblockSize;
int endSize = ( i + 1 )blockSize - 1;
//开启线程
new DownThread_2(localPath,onlinePath,"线程:"+i,startSize,endSize).start();
}//线程是否结束,显示进度条
//DownLoadParam 类内存储着是否完成 下载数量
while (DownLoadParam.finish) {
Thread.sleep(500); //间隔0.5秒计算一下
if (DownLoadParam.downSize == fileLength) {
DownLoadParam.finish = false;
System.out.println("下载完成:100%");
} else {
System.out.println("已经下载了:" + ((int) (float) DownLoadParam.downSize / (float) fileLength * 100) + "%");
}
}
}
}catch (Exception e ){
log.error("userThread:error",e);
}}
}
` -
多线程
`@Slf4j
public class DownThread_2 extends Thread{
//下载文件地址
private String localFilePath;
//文件地址
private String onlineFilePath;
//线程名称-自己传过来
private String threadName;
//开始位置
private int startPosition;
//结束位置
private int endPosition;public DownThread_2(String localFilePath,String onlineFilePath,String threadName,
Integer startPosition,int endPosition){
this.localFilePath = localFilePath ;
this.onlineFilePath = onlineFilePath ;
this.threadName = threadName ;
this.startPosition = startPosition ;
this.endPosition = endPosition ;
}@Override
public void run() {
try {//url 链接onlinePath
URL url = new URL(onlineFilePath);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
//设置 下载的 开始结束 range?
conn.setRequestProperty("range","bytes="+startPosition+"-"+endPosition);
//超时连接
conn.setConnectTimeout(500);//链接响应代码 206 才是成功 因为设置了range
int responseCode = conn.getResponseCode();if( responseCode == 206 ){
//成功后 读数据
BufferedInputStream bis = new BufferedInputStream(conn.getInputStream());
//开始读写数据
RandomAccessFile raf = new RandomAccessFile(localFilePath,"rwd");
raf.seek(startPosition);
byte[] bytes = new byte[1024];
int len ;while( (len = bis.read(bytes)) > -1){
raf.write(bytes,0,len);
//加锁唯一
synchronized (DownLoadParam.class){
DownLoadParam.downSize = DownLoadParam.downSize+len;
}}
raf.close();
bis.close();
log.info("线程{}开始下载:{}---{}",threadName,startPosition,endPosition);
}}catch ( Exception e){
log.error("线程{},异常",threadName,e);
}
}
}
` -
共享参数
public class DownLoadParam { //已经下载多少 静态 在方法区 共享资源 public static int downSize = 0; //是否下载完 public static boolean finish = true; }

浙公网安备 33010602011771号