블로그 내 검색

2010. 7. 22.

파일 MimeType 을 구별하는 다양한 방법

파일의 마임 타입(Mime-Type)은 정말 다양하며 때때로 그걸 구별해야 할 필요가 생긴다.

문제는 받아온 파일의 확장자가 jpg라고 그 파일마저 jpg이진 않다는 것이다.
혹은 확장자가 없거나 하는 일도 있어 그 파일의 정체를 알고 싶다면 다른 방법을 써 봐야 한다.

요새는 프로그램들이 좋아져서 파일에 대고 연결프로그램으로 대충 열기를 시도해보면 열리긴 하지만, 이걸 프로그램에 포함시키기엔 무리가 있다.

마임 타입을 구별할 수 있는 방법에 대해 조금 알아보자.


1. (웹서버 다운로드의 경우) HTTP 헤더의 컨텐트 타입 값을 검사

이 방법은 어떻게보면 아주 순수한 작업이다. 웹 서버를 매우 신뢰할 때 할 수 있는 방법이다.
그러나 세상은 그리 순수하지 않고 IT의 세계는 더욱 진흙탕 바닥이다.
HTTP 헤더는 그냥 서버측에서 간단한 조작만으로 변경이 가능하다. 응답하는 데이터가 image/gif 인데도 응답을 text/plain 으로 응답을 조작할 수 있다.

이 방법은 타입 구별이 그저 "옵션" 일 경우에나 적합한 방법이라 볼 수 있다.


2. 파일 컨텐트의 바이트를 검사

이 방법이 역시 제일 정확한 방법이다.
모든 파일(text 파일 제외)에는 이 파일이 어떠한 포맷이라는걸 알려주는 고유의 시그니쳐 바이트가 존재한다.
그 길이는 파일마다 다르며, 종류또한 파일의 포맷만큼 많다.

예를 들어 image/jpg 의 파일을 바이트스트림으로 읽어 표시하면 다음과 같은 헥스값을 볼 수 있다.

FF D8....

어떠한 종류의 JPG 파일도 반드시 저것으로 시작한다 는걸 보장할 수 있다.

그러나 여기서 문제가 또 생긴다.
어느 포맷이 어느 시그니쳐를 가지는가에 대한 사전정보가 없다.
그리고 그 포맷의 앞 어느 바이트까지가 교유한 시그니쳐인가에 대한 정보또한 없다.

물론 파일 포맷을 모두 수집하여 하나하나 분석한뒤 자신의 사전을 구축하고 그걸 토대로 프로그래밍할 수 있다. 그러나 놀 시간도 없는 판국에 이러한 짓을 하기보다는 위대한 선구자들의 경험을 빌려보자.

참고로 파일 시그너쳐 테이블이 나온 페이지를 소개해둔다. 이곳을 클릭해보자

이제 Java에서 MimeType을 구별하는 방법에 대해 알아보자.

3. Java Code 사용한 구별법

몇 가지 파일 타입을 구별하는 방법이다.

= MimetypesFileTypeMap을 사용
File f = new File("gumby.gif");
System.out.println(new MimetypesFileTypeMap().getContentType(f));

= URLConnection 을 사용하는 방법 (굉장히 느리다! 주의가 필요...)
import java.net.*;

public class FileUtils{
    public static String getMimeType(String fileUrl)
    throws java.io.IOException, MalformedURLException 
    {
        String type = null;
        URL u = new URL(fileUrl);
        URLConnection uc = null;
        uc = u.openConnection();
        type = uc.getContentType();
        return type;
    }

    public static void main(String args[]) throws Exception {
        System.out.println(FileUtils.getMimeType("file://c:/temp/test.TXT"));

        // FileNameMap을 사용하는 우회적 방법...이건 좀 빠른편
        //FileNameMap fileNameMap = URLConnection.getFileNameMap();
        //String contentType = fileNameMap.getContentTypeFor(text.txt);
    }
}

= Apache Tika 을 사용하는 방법
String mimeType = null;
try {
    Tika tika = new Tika();
    mimeType = tika.detect(file);
} 
catch (Exception e) {
    System.err.println("오류");
}
System.err.println(mimeType);
위 세가지 방법중 추천할만한건 역시 Tika를 사용한 파싱 방법이다.
다양한 파일을 구분해낼 수 있다.

Apache Tika 의 공식 프로젝트 문서는 이곳(http://tika.apache.org/)으로.
웹 크롤러 작업시 꽤 도움을 받았다.

댓글 1개:

  1. 어떤 jpg 라면.. 안의 내용은 스크립트만 존재하는 jpg 파일도 똑같이 hex 가 나오나요?

    답글삭제