자바 프로그래밍에서 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());
}
댓글