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

    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>

     

    댓글

    Designed by JB FACTORY