Java
Internet
File Download
Programming
Coding Tutorial

How can I download and save a file from the Internet using Java?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Downloading a file in Java is mostly an I/O problem: open a network stream, copy the bytes, and close resources safely. The main engineering concerns are not the copy loop itself, but timeouts, HTTP status handling, and making sure partial downloads do not silently look successful.

A Simple Standard-Library Approach

The classic approach is to open a URL stream and copy the bytes to a file. Files.copy makes this concise.

java
1import java.io.InputStream;
2import java.net.URL;
3import java.nio.file.Files;
4import java.nio.file.Path;
5import java.nio.file.StandardCopyOption;
6
7public class DownloadDemo {
8    public static void main(String[] args) throws Exception {
9        URL url = new URL("https://example.com/file.zip");
10        Path target = Path.of("file.zip");
11
12        try (InputStream in = url.openStream()) {
13            Files.copy(in, target, StandardCopyOption.REPLACE_EXISTING);
14        }
15    }
16}

This is fine for quick utilities, but it gives you limited control over HTTP details.

Prefer HttpClient for Real HTTP Downloads

For production code on modern Java, java.net.http.HttpClient is usually the better choice. It gives you explicit response handling and cleaner timeout configuration.

java
1import java.net.URI;
2import java.net.http.HttpClient;
3import java.net.http.HttpRequest;
4import java.net.http.HttpResponse;
5import java.nio.file.Path;
6import java.time.Duration;
7
8public class DownloadDemo {
9    public static void main(String[] args) throws Exception {
10        HttpClient client = HttpClient.newBuilder()
11                .connectTimeout(Duration.ofSeconds(10))
12                .build();
13
14        HttpRequest request = HttpRequest.newBuilder()
15                .uri(URI.create("https://example.com/file.zip"))
16                .timeout(Duration.ofSeconds(30))
17                .build();
18
19        HttpResponse<Path> response = client.send(
20                request,
21                HttpResponse.BodyHandlers.ofFile(Path.of("file.zip"))
22        );
23
24        if (response.statusCode() != 200) {
25            throw new IllegalStateException("download failed: " + response.statusCode());
26        }
27    }
28}

That pattern makes it much easier to reject redirects, auth failures, and server errors explicitly.

Validate What You Download

A downloaded file is not automatically a correct file. You may want to validate:

  • HTTP status code
  • content length if known
  • file type or checksum
  • target path and overwrite behavior

If the source provides a checksum, verify it after download rather than assuming the transport completed correctly.

Be Careful With Large Files

Large downloads raise two practical concerns: storage and interruption. If the file is huge, make sure the target directory exists and has enough space. If download interruption matters, consider writing to a temporary file first and moving it into place only after the transfer succeeds.

That avoids leaving a half-written file behind with the final name.

Keep Networking Concerns Out of Utility Callers

It is often cleaner to wrap download behavior in a small helper instead of scattering HTTP and file-copy code everywhere.

java
1import java.net.URI;
2import java.net.http.HttpClient;
3import java.net.http.HttpRequest;
4import java.net.http.HttpResponse;
5import java.nio.file.Path;
6
7public class FileDownloader {
8    private final HttpClient client = HttpClient.newHttpClient();
9
10    public Path download(String url, Path target) throws Exception {
11        HttpRequest request = HttpRequest.newBuilder(URI.create(url)).build();
12        HttpResponse<Path> response = client.send(request, HttpResponse.BodyHandlers.ofFile(target));
13        if (response.statusCode() != 200) {
14            throw new IllegalStateException("unexpected status: " + response.statusCode());
15        }
16        return response.body();
17    }
18}

A helper like that is easier to test and extend with retries, headers, or authentication later.

Common Pitfalls

The biggest mistake is ignoring the HTTP status code and assuming a saved file means a successful download. Error pages can also be written to disk.

Another issue is skipping timeouts, which can leave threads hanging on slow or broken connections.

A third problem is writing directly to the final path without considering partial-download cleanup.

Summary

  • Downloading a file in Java means copying a network response stream to disk safely.
  • 'Files.copy is fine for simple cases.'
  • 'HttpClient is usually the better option for real HTTP handling.'
  • Check the response status instead of trusting that the file is valid.
  • Use temporary files and cleanup strategy when partial downloads matter.

Course illustration
Course illustration

All Rights Reserved.