java 如何下载文件
使用 URL 和 HttpURLConnection 下载文件
通过 java.net.URL 和 HttpURLConnection 建立连接,读取输入流并写入本地文件。需要处理 HTTP 响应码和异常。
URL url = new URL("http://example.com/file.zip");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
int responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
try (InputStream inputStream = connection.getInputStream();
FileOutputStream outputStream = new FileOutputStream("local_file.zip")) {
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
}
} else {
throw new IOException("Server returned non-OK status: " + responseCode);
}
使用 Apache HttpClient 下载文件
引入 Apache HttpClient 依赖(如 org.apache.httpcomponents:httpclient),通过 CloseableHttpClient 发送请求并处理响应流。

CloseableHttpClient client = HttpClients.createDefault();
HttpGet request = new HttpGet("http://example.com/file.zip");
try (CloseableHttpResponse response = client.execute(request);
InputStream inputStream = response.getEntity().getContent();
FileOutputStream outputStream = new FileOutputStream("local_file.zip")) {
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
}
使用 Java NIO 的 Files.copy 方法
Java 7+ 的 Files.copy 方法可直接将输入流复制到目标路径,简化代码。

URL url = new URL("http://example.com/file.zip");
try (InputStream inputStream = url.openStream()) {
Files.copy(inputStream, Paths.get("local_file.zip"), StandardCopyOption.REPLACE_EXISTING);
}
处理大文件下载的进度监控
通过自定义 InputStream 包装类或回调接口实现下载进度跟踪。
try (InputStream inputStream = connection.getInputStream();
FileOutputStream outputStream = new FileOutputStream("local_file.zip")) {
byte[] buffer = new byte[4096];
int totalBytesRead = 0;
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
totalBytesRead += bytesRead;
System.out.println("Downloaded: " + totalBytesRead + " bytes");
}
}
异步下载文件
结合 CompletableFuture 或线程池实现异步下载,避免阻塞主线程。
ExecutorService executor = Executors.newFixedThreadPool(1);
Future<?> future = executor.submit(() -> {
URL url = new URL("http://example.com/file.zip");
try (InputStream in = url.openStream()) {
Files.copy(in, Paths.get("local_file.zip"));
}
});
// 可调用 future.get() 等待下载完成
注意事项
- 添加超时设置:通过
connection.setConnectTimeout(5000)防止网络阻塞。 - 关闭资源:确保
InputStream、OutputStream和连接在try-with-resources中自动关闭。 - 错误处理:检查 HTTP 状态码(如 404、503)并重试或终止。
- 文件名处理:从
Content-Disposition头或 URL 路径解析原始文件名。
以上方法覆盖了从基础到进阶的文件下载需求,可根据项目依赖和复杂度选择合适方案。






