本文目录导读:

我来详细讲解Java实现文件下载的几种常见方式。
基础HTTP文件下载(URL Connection)
简单文件下载
import java.io.*;
import java.net.*;
public class FileDownloader {
public static void downloadFile(String fileURL, String savePath) throws IOException {
URL url = new URL(fileURL);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
// 设置请求属性
connection.setRequestMethod("GET");
connection.setConnectTimeout(5000);
connection.setReadTimeout(5000);
// 获取输入流
try (InputStream inputStream = connection.getInputStream();
FileOutputStream outputStream = new FileOutputStream(savePath)) {
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
}
System.out.println("文件下载完成: " + savePath);
}
public static void main(String[] args) {
try {
downloadFile("https://example.com/file.pdf", "downloaded_file.pdf");
} catch (IOException e) {
e.printStackTrace();
}
}
}
带进度条的下载
public class FileDownloadWithProgress {
public static void downloadWithProgress(String fileURL, String savePath) throws IOException {
URL url = new URL(fileURL);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
// 获取文件大小
int fileSize = connection.getContentLength();
System.out.println("文件大小: " + fileSize + " bytes");
try (InputStream inputStream = connection.getInputStream();
FileOutputStream outputStream = new FileOutputStream(savePath)) {
byte[] buffer = new byte[4096];
int bytesRead;
int totalBytesRead = 0;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
totalBytesRead += bytesRead;
// 计算并显示进度
if (fileSize > 0) {
int progress = (int) ((totalBytesRead * 100) / fileSize);
System.out.print("\r下载进度: " + progress + "%");
}
}
System.out.println("\n下载完成!");
}
}
}
断点续传下载
public class ResumeDownload {
public static void resumeDownload(String fileURL, String savePath) throws IOException {
File file = new File(savePath);
long existingFileSize = 0;
// 检查是否已有部分下载的文件
if (file.exists()) {
existingFileSize = file.length();
System.out.println("已有部分下载文件,大小: " + existingFileSize + " bytes");
}
URL url = new URL(fileURL);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
// 设置断点续传请求头
if (existingFileSize > 0) {
connection.setRequestProperty("Range", "bytes=" + existingFileSize + "-");
}
int responseCode = connection.getResponseCode();
// 206表示部分内容,支持断点续传
if (responseCode == HttpURLConnection.HTTP_PARTIAL || responseCode == HttpURLConnection.HTTP_OK) {
try (InputStream inputStream = connection.getInputStream();
FileOutputStream outputStream = new FileOutputStream(savePath, true)) {
byte[] buffer = new byte[4096];
int bytesRead;
long totalBytesRead = existingFileSize;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
totalBytesRead += bytesRead;
System.out.print("\r已下载: " + totalBytesRead + " bytes");
}
System.out.println("\n下载完成!");
}
}
}
}
使用Apache HttpClient
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.HttpEntity;
public class HttpClientDownload {
public static void downloadWithHttpClient(String fileURL, String savePath) throws Exception {
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
HttpGet httpGet = new HttpGet(fileURL);
try (CloseableHttpResponse response = httpClient.execute(httpGet)) {
HttpEntity entity = response.getEntity();
if (entity != null) {
try (InputStream inputStream = entity.getContent();
FileOutputStream outputStream = new FileOutputStream(savePath)) {
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
}
}
}
}
System.out.println("下载完成");
}
}
Web应用中的文件下载(Servlet)
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
@WebServlet("/download")
public class FileDownloadServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String fileName = request.getParameter("file");
String filePath = "/path/to/your/files/" + fileName;
File file = new File(filePath);
if (!file.exists()) {
response.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
// 设置响应头
response.setContentType("application/octet-stream");
response.setContentLength((int) file.length());
response.setHeader("Content-Disposition",
"attachment; filename=\"" + fileName + "\"");
// 写入文件内容
try (FileInputStream inputStream = new FileInputStream(file);
OutputStream outputStream = response.getOutputStream()) {
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
}
}
}
多线程下载
public class MultiThreadDownload {
private static final int THREAD_COUNT = 4;
public static void downloadWithMultiThread(String fileURL, String savePath) throws Exception {
URL url = new URL(fileURL);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
int fileSize = connection.getContentLength();
connection.disconnect();
int partSize = fileSize / THREAD_COUNT;
List<DownloadThread> threads = new ArrayList<>();
// 创建并启动多个下载线程
for (int i = 0; i < THREAD_COUNT; i++) {
int start = i * partSize;
int end = (i == THREAD_COUNT - 1) ? fileSize - 1 : (start + partSize - 1);
DownloadThread thread = new DownloadThread(fileURL, savePath, start, end, i);
threads.add(thread);
thread.start();
}
// 等待所有线程完成
for (DownloadThread thread : threads) {
thread.join();
}
// 合并文件
mergeFiles(savePath, THREAD_COUNT);
}
static class DownloadThread extends Thread {
private String fileURL;
private String savePath;
private int start;
private int end;
private int threadId;
public DownloadThread(String fileURL, String savePath, int start, int end, int threadId) {
this.fileURL = fileURL;
this.savePath = savePath;
this.start = start;
this.end = end;
this.threadId = threadId;
}
@Override
public void run() {
try {
URL url = new URL(fileURL);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestProperty("Range", "bytes=" + start + "-" + end);
try (InputStream inputStream = connection.getInputStream();
RandomAccessFile outputFile = new RandomAccessFile(savePath + ".part" + threadId, "rw")) {
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputFile.write(buffer, 0, bytesRead);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
private static void mergeFiles(String savePath, int threadCount) throws IOException {
try (FileOutputStream outputStream = new FileOutputStream(savePath)) {
for (int i = 0; i < threadCount; i++) {
File partFile = new File(savePath + ".part" + i);
try (FileInputStream inputStream = new FileInputStream(partFile)) {
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
}
partFile.delete();
}
}
}
}
异常处理与重试机制
public class DownloadWithRetry {
private static final int MAX_RETRIES = 3;
private static final int RETRY_DELAY_MS = 2000;
public static void downloadWithRetry(String fileURL, String savePath) {
int retries = 0;
boolean success = false;
while (retries < MAX_RETRIES && !success) {
try {
downloadFile(fileURL, savePath);
success = true;
System.out.println("下载成功");
} catch (IOException e) {
retries++;
System.err.println("下载失败 (尝试 " + retries + "/" + MAX_RETRIES + "): " + e.getMessage());
if (retries < MAX_RETRIES) {
try {
Thread.sleep(RETRY_DELAY_MS);
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
break;
}
}
}
}
if (!success) {
System.err.println("下载失败,已重试 " + MAX_RETRIES + " 次");
}
}
}
完整的使用示例
public class CompleteDownloadExample {
public static void main(String[] args) {
String fileURL = "https://example.com/large-file.zip";
String savePath = "downloads/large-file.zip";
// 创建下载目录
new File("downloads").mkdirs();
try {
// 基础下载
// FileDownloader.downloadFile(fileURL, savePath);
// 带进度条下载
// FileDownloadWithProgress.downloadWithProgress(fileURL, savePath);
// 断点续传
// ResumeDownload.resumeDownload(fileURL, savePath);
// 多线程下载
// MultiThreadDownload.downloadWithMultiThread(fileURL, savePath);
} catch (Exception e) {
e.printStackTrace();
}
}
}
- 资源管理:使用 try-with-resources 自动关闭流
- 缓冲处理:使用缓冲区提高性能(4096 bytes 是常用值)
- 异常处理:处理网络超时、文件不存在等情况
- 编码问题:正确处理文件名编码
- 大文件处理:考虑使用断点续传或多线程下载
- 安全性:验证URL合法性,防止路径遍历攻击
选择哪种方式取决于你的具体需求,如文件大小、网络稳定性、是否需要断点续传等。
版权声明:足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播