利用java写一个多线程文件下载器
时间: 2023-08-05 10:48:59 浏览: 116
下面是一个简单的多线程文件下载器示例代码:
```java
import java.io.*;
import java.net.URL;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class MultiThreadDownloader {
private static final int MAX_THREADS = 5; // 最大线程数
private static final int BUFFER_SIZE = 1024; // 缓冲区大小
public static void main(String[] args) {
String url = "http://example.com/file.zip"; // 下载文件的URL
String fileName = "file.zip"; // 下载保存的文件名
int fileSize = getFileSize(url); // 获取文件大小
ExecutorService executor = Executors.newFixedThreadPool(MAX_THREADS); // 创建线程池
int blockSize = fileSize / MAX_THREADS; // 计算每个线程下载的块大小
for (int i = 0; i < MAX_THREADS; i++) {
int start = i * blockSize; // 计算每个线程下载的起始位置
int end = (i == MAX_THREADS - 1) ? fileSize - 1 : (i + 1) * blockSize - 1; // 计算每个线程下载的结束位置
// 创建下载线程并启动
executor.execute(new DownloadThread(url, fileName, start, end));
}
executor.shutdown(); // 等待所有线程完成
}
// 获取文件大小
private static int getFileSize(String urlStr) {
try {
URL url = new URL(urlStr);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("HEAD");
return conn.getContentLength();
} catch (IOException e) {
e.printStackTrace();
return -1;
}
}
// 下载线程类
private static class DownloadThread implements Runnable {
private String url;
private String fileName;
private int start;
private int end;
public DownloadThread(String url, String fileName, int start, int end) {
this.url = url;
this.fileName = fileName;
this.start = start;
this.end = end;
}
public void run() {
try {
URL urlObj = new URL(url);
HttpURLConnection conn = (HttpURLConnection) urlObj.openConnection();
conn.setRequestProperty("Range", "bytes=" + start + "-" + end);
InputStream inputStream = conn.getInputStream();
RandomAccessFile file = new RandomAccessFile(fileName, "rw");
file.seek(start);
byte[] buffer = new byte[BUFFER_SIZE];
int len;
while ((len = inputStream.read(buffer)) != -1) {
file.write(buffer, 0, len);
}
inputStream.close();
file.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
```
该程序通过创建多个线程来下载同一个文件,每个线程下载文件的不同部分,最后将所有部分合并成完整文件。程序通过获取文件大小来计算每个线程下载的块大小和位置,然后使用HttpURLConnection发送Range请求,下载指定的部分数据。下载的数据使用RandomAccessFile类保存到本地文件中。
该程序使用了线程池来管理多个下载线程,可以控制最大线程数,避免创建过多线程导致系统资源浪费。同时,使用线程池可以避免线程频繁创建和销毁的开销,提高了程序的性能。
阅读全文