본문 바로가기
Old Posts/Java

[Java] InputStream 객체와 File 객체 상호 변환하기

by A6K 2021. 5. 26.

자바 프로그래밍에서 InputStream 객체를 File 객체로 만들거나 File 객체를 InputStream 객체로 만들어야 할 경우가 종종있다. 사용하고자하는 API에서 어떤 객체를 입력으로 받는지에 따라 상호변환이 필요할 수 있다.

File 객체에서 InputStream 객체 얻기

우선 File 객체를 InputStream 객체로 만들어보자.

File file = new File("path to file");

InputStream inputStream = new FileInputStream(file);

 FileInputStream 객체를 생성할 때, File 객체를 넘겨주면 된다. 간단한 사용법이다.

InputStream 객체에서 File 객체 만들기

InputStream 객체는 어디에선가 데이터를 읽어들이는 객체다. 여기서 읽은 데이터를 임시파일에 저장을 해 놓은 다음 임시파일에 대한 File 객체를 만드는 식으로 구현해볼 수 있다. 

public static File convertInputStreamToFile(InputStream in) {

    File tempFile = File.createTempFile(String.valueOf(inputStream.hashCode()), ".tmp");
    tempFile.deleteOnExit();

    copyInputStreamToFile(inputStream, tempFile);

    return tempFile;
}

File.createTempFile() 메소드를 이용해서 임시 파일을 생성한다. 이 때, inputStream의 해시코드를 이용해서 임시 파일을 생성해야 다른 inputStream과 겹치지 않게 된다. 만들어진 임시파일은 deleteOnExit() 메소드를 이용해서 JVM이 종료될 때 함께 지워지도록 설정해준다. 자바 프로그램이 종료되고 나서는 의미가 없는 파일인 경우 이렇게 많이 설정한다.

copyInputStreamToFile() 메소드를 이용해서 InputStream에서 데이터를 읽은 후 임시 파일에 써주고, 임시 파일에 대한 File 객체를 리턴하면 된다. copyInputStreamToFile() 메소드는 다음과 같이 구현할 수 있다.

private static void copyInputStreamToFile(InputStream inputStream, File file) {

    try (FileOutputStream outputStream = new FileOutputStream(file)) {
        int read;
        byte[] bytes = new byte[1024];

        while ((read = inputStream.read(bytes)) != -1) {
            outputStream.write(bytes, 0, read);
        }
    }
}

중간에 1024바이트짜리 버퍼를 두고 InputStream에서 데이터를 읽어 임시파일로 쓴다.

같은 동작을 하는 코드가 Apache Commons I/O 라이브러리에 구현되어 있다. 아파치 라이브러리를 이용하면 다음처럼 짧게 구현할 수 있다.

private static void copyInputStreamToFile(InputStream inputStream, File file) {

    FileUtils.copyInputStreamToFile(inputStream, file);
}

이 라이브러리를 사용하기 위해서는 메이븐 의존성을 추가해줘야한다.

<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.6</version>
<dependency>

자바 1.7 이상을 사용한다면 NIO를 이용할 수도 있다.

private static void copyInputStreamToFile(InputStream inputStream, File file) {

    Files.copy(inputStream, file.toPath());
}

 

댓글