프로그램언어/자바(Java)

[Java] Http URL File download 3가지 방법

Steve Jang 2021. 12. 29. 09:58

Java에는 Http 상의 데이터 즉, URL 기반으로 파일을 download할 수 있는 다양한 라이브러리들이 있고, 기본 버전으로도 제공을 하고 있다. 본 포스팅은 3가지의 대표적인 방법들을 모두 써보고 비교하여 성능을 점검해보도록 하였다.

 

[Java] URL File download 3가지 방법

 

고전적인 방법

 public static void fileDown(String url, String fileName) throws MalformedURLException, IOException {
	BufferedInputStream in = null;
    FileOutputStream fout = null;
    try {
        in = new BufferedInputStream(new URL(url).openStream());
        fout = new FileOutputStream(fileName);

        final byte data[] = new byte[1024];
        int count;
        while ((count = in.read(data, 0, 1024)) != -1) {
            fout.write(data, 0, count);
        }
    } finally {
        if (in != null) {
            in.close();
        }
        if (fout != null) {
            fout.close();
        }
    }
}

 

자바를 어느정도 개발했던 사람이라면 이런 류의 코드를 안써보거나 안본 사람은 없을 것이다. input stream을 읽어서 write를 하여 기록을 하는 기본적인 방법이다. 다만 코드가 매우 지저분해보일 수 있기에 최근에는 아래와 같은 방법들을 사용한다.

 

Files.copy 자바 7.0 이상

public static void fileDown1(String url, String fileName) throws IOException {
	try (InputStream in = URI.create(url).toURL().openStream()) {
		Files.copy(in, Paths.get(fileName));
	}
}

 

다만 위 방법은 자바 7.0 이상인데 사실 금융권이나 오래된 사이트가 아닌 이상 Java는 대부분 1.8이상을 쓰기 때문에 이렇게 구현하는 사람들이 이제는 꽤 많을 것이다.

 

하지만 위 방법은 치명적인 단점이 한가지 있는데 이미 파일이 있을 경우, overwrite를 하지 않고 에러가 떨어진다는 점이다. 

동일한 파일 있을 경우 에러가 떨어지는 모습

Exception in thread "main" java.nio.file.FileAlreadyExistsException: C:\Project\test\1.pdf
	at sun.nio.fs.WindowsException.translateToIOException(Unknown Source)
	at sun.nio.fs.WindowsException.rethrowAsIOException(Unknown Source)
	at sun.nio.fs.WindowsException.rethrowAsIOException(Unknown Source)
	at sun.nio.fs.WindowsFileSystemProvider.newByteChannel(Unknown Source)
	at java.nio.file.spi.FileSystemProvider.newOutputStream(Unknown Source)
	at java.nio.file.Files.newOutputStream(Unknown Source)
	at java.nio.file.Files.copy(Unknown Source)
	at Test.fileDown1(Test.java:36)
	at Test.main(Test.java:21)

이미 동일한 파일이 있을 시 overwrite하고 싶은 경우 File 객체로 exist를 호출하여 파일이 있는지 체크한 후 있을 경우 delete한후 호출해야 하는 불편함이 있다.

 

Apache Common FileUtils

import org.apache.commons.io.FileUtils;

public static void fileDown2(String url, String fileName) throws MalformedURLException, IOException {
	File f = new File(fileName);
	FileUtils.copyURLToFile(new URL(url), f);
}

첫번째 방식과 두번째 방식의 장점을 합친 것이 아파치 라이브러리라 할 수 있다. URL 객체와 File 객체를 아규먼트로 던지면 끝인 심플한 방식인데 기본 라이브러리가 아니기 때문에 commons.io 라이브러리를 받아야 한다. 

 

https://commons.apache.org/proper/commons-io/download_io.cgi

 

Commons IO – Download Apache Commons IO

Download Apache Commons IO Using a Mirror We recommend you use a mirror to download our release builds, but you must verify the integrity of the downloaded files using signatures downloaded from our main distribution directories. Recent releases (48 hours)

commons.apache.org

 

commons-io maven

<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.11.0</version>
</dependency>