2015. 3. 1.

자바에서 파일 타입을 확인하는 방법들... 그리고 Apache Tika...

뭐 역시나 내가 직접 조사한 것은 아니고 Java Code Geeks 에서 본 내용에 대한 정리이다.

자세한 사항은 [원문보기] 를 클릭해서 확인하면 된다.
원문에서는 코드와 스크린샷을 포함한 예제를 확인할 수 있으니 내용을 보시고자 하시는 분들은 꼭 원문을 참고하시길...
내가 쓰는 포스트가 대부분 그렇지만, 이 글도 그저 내용을 정리해서 내가 나중에 확인하기 위해 쓰는 글일 뿐...

1. Files.probeContentType(Path)를 이용하는 방법 [JDK 7]

이 방법은 파일 확장자를 이용해서 판단하는 것으로 보인다. 즉, gif 파일을 png라고 확장자를 주면 png 로 인식한다는 것. 또 확장자가 없는 파일의 경우는 null 을 리턴한다.

2. MimetypesFileTypeMap.getContentType(String) 을 이용하는 방법 [JDK 6]

이 방법은 클래스 명에서 유추가 가능한 것 처럼 Mime type 을 이용한다.
앞서의 경우와 같이 gif 파일을 png 라고 하거나 pdf 파일을 txt 로 하거나 하면 확장자로 판단을 한다. 1번 경우와 다른 점을 이야기하자면 기본적으로 텍스트나 이미지 확장자가 아닌 경우에는 xml 파일을 포함해서 application/octet-stream을 반환한다. 또한 확장자가 없는 파일의 경우도 application/octet-stream을 반환한다.

3. URLConnection.getContentType()

이 방법 역시 확장자에 의한 판단. 대신 null 대신 content/unknown을 반환

4. URLConnection.guessContentTypeFromName(String)

역시 확장자. 3번과 다른 것은 null을 반환.

5. URLConnection.guessContentTypeFromStream(InputStream)

예제에서는 전부 null 을 반환. 저자의 설명에 따르면 여기서 매개변수로 주어진 InputStream은 marks를 지원하는 것이어야만 한다고 함. 저자가 예제에서 사용한 FileInputStream의 경우는 markSupported() 메소드를 호출해 본 결과 false 였기 때문에 모두 null이라는 설명.
BufferedInputStream은 mark 를 지원하니 나중에 BufferedInputStream 을 이용해서 한번 해 봐야겠다.

6. Apache Tika 를 이용하는 방법

Tika 는 아래의 세가지 경우로 나눠서 설명하고 있다.

  • Tika defaultTika = new Tika()
  • Tika mimeTika = new Tika(new MimeTypes())
  • Tika typeTika = new Tika(new TypeDetector())
세가지 모두 detect(fileName) 형식으로 했을 경우에는 앞서의 경우와 별반 다르지 않은 결과였다.

그러나, File 객체로 만들어서 해당 file 객체를 detect의 매개변수로 넣었을 경우에는 defaultTika 에서 매우 정확한 결과를 반환하고 있다. 즉 확장자가 txt 인 pdf 파일은 pdf 로 확장자가 없는 pdf 또는 txt 파일도 정확하게 결과를 반환하고 있다.


저자도 설명하고 있지만, 일반적으로 지금까지 진행했던 프로젝트들은 파일 확장자 만으로 판단을 해도 충분한 경우가 많았다. 가끔은 정상적인 이미지 파일인지 판단해야 하는 경우가 있긴 했지만, 아주 오래전으로 요즘 들어서는 거의 간단히 확장자 만으로 판단하고 넘어가곤 한다. (최근 5년 이상은 일반 사용자를 상대로 파일 업로드 처리를 해야 하는 경우가 없었기 때문일 수도 있지만...)
아무튼 어떠한 이유건 파일 타입을 정확히 판단해야 한다면 단순 자바로는 쉬운 일이 아님에는 분명하다. 다른 많은 라이브러리들이 있겠지만, Apache Tika 도 하나의 해결책이 되지 않을 까 싶다.