파일 타입을 좀 더 정확하게 확인하도록 도와주는 자바 라이브러리

파일을 처리하는 애플리케이션을 개발하면서 많은 경우에 파일 처리는 확장자를 기준으로 파일의 타입을 결정하고 처리하게 된다. 예를 들면, 확장자가 .docx 이면 마이크로소프트 워드 파일이라는 것을 알 수 있고, 이 파일의 타입에 적합하게 처리(오픈 등)한다. 이 블로그의 파일 타입별 확장자 분류.. 포스팅을 확인해 보면, 비교적 자주 사용되는 파일 확장자와 그 확장자를 가지고 있는 파일이 어떤 타입의 파일인지 확인할 수 있다.

파일의 포맷을 인식하는 기본 방법이 확장자를 기준으로 타입을 구분해서 처리하는 방법이지만, 종종 파일의 타입을 알 수 없는 경우가 발생한다. 이런 경우는 다음과 같다.
– 수동으로 파일의 확장자를 수정한다.
– 특정 폴더에 이미지의 썸네일을 확장자 없이 저장(안드로이드에서 종종 볼 수 있다)한다.
– 각종 다운로드로 인해서 발생한다.

일반적으로 위 경우에는 파일을 처리하지 못하거나, 제대로 열 수 없는 애플리케이션을 호출하게 된다. 따라서 좀 더 정확하게 파일을 처리하기 위해서는 파일의 헤더를 분석해서 파일의 타입을 확인하고, 그 타입에 맞는 처리가 필요하다. 그래서, 이 글에서는 자바로 파일의 타입을 정확하게 확인할 수 있는 라이브러리를 확인해 보겠다.

파일의 타입을 확인할 수 있는 자바 라이브러리를 찾아보면 아래의 목록을 확인할 수 있다. 그리고 이 라이브러리는 안드로이드에서도 사용할 수 있다.

  1. SimpleMagic
    1. https://github.com/j256/simplemagic
    2. 의존 : 없음
  2. Java Mime Magic Library
    1. https://github.com/arimus/jmimemagic
    2. 의존 : Apache Common Logging 라이브러리
  3.  Apache Tika
    1. http://tika.apache.org/
    2. 의존 : 많음

이 글에서는 Apache Tika는 제외하고, 1.번과 2.번의 라이브러리를 확인해 보겠다. Apache Tika를 제외한 이유는 의존하는 라이브러리가 너무 많아서이다. 대상은 아래에 있는 5개 타입에 대해서 확인해 봤다.

docx = new java.io.File(".").getCanonicalPath()     + "/files/docx_file";
jpg = new java.io.File(".").getCanonicalPath() + "/files/jpg_file";
odt = new java.io.File(".").getCanonicalPath() + "/files/open_office_odt_file";
pdf = new java.io.File(".").getCanonicalPath() + "/files/pdf_file";
exe = new java.io.File(".").getCanonicalPath() + "/files/prgrep_exe_file";

위에서 파일의 확장자를 수동으로 변경했고, 이 파일에 대해서 포맷을 정확하게 인식하는 것을 테스트 했고, 결과는 다음과 같다.

– SimpleMagic 결과

0 ContentType : word
0 MimeType : application/vnd.openxmlformats-officedocument.wordprocessingml.document
0 File Extension 0 : docx
1 ContentType : jpeg
1 MimeType : image/jpeg
1 File Extension 0 : jpeg
1 File Extension 1 : jpg
1 File Extension 2 : jpe
2 ContentType : opendocument-text
2 MimeType : application/vnd.oasis.opendocument.text
2 File Extension 0 : odt
3 ContentType : pdf
3 MimeType : application/pdf
3 File Extension 0 : pdf
4 Unknown content-type

– Java Mime Magic Library 결과

0 File Ext : zip
0 File Mimetype : application/zip
1 File Ext : jpg
1 File Mimetype : image/jpeg
2 File Ext : zip
2 File Mimetype : application/zip
3 File Ext : pdf
3 File Mimetype : application/pdf
4 File Ext : ???
4 File Mimetype : ???

위 개별 라이브러리의 파일 타입 인식 결과로, 자바를 사용해서 파일의 포맷을 더 정확하게 확인하고 사용하려면, SimpleMagic 라이브러를 사용해서 파일의 타입을 확인하는게 좋겠다. 이 테스트를 위해서 사용한 소스는 다음과 같다.

import java.io.File;
import java.io.IOException;

import net.sf.jmimemagic.Magic;
import net.sf.jmimemagic.MagicMatch;

import com.j256.simplemagic.ContentInfo;
import com.j256.simplemagic.ContentInfoUtil;

public class FileFormatCheckTest {

	static String[] files = null;

	static String docx = "";
	static String jpg = "";
	static String odt = "";
	static String pdf = "";
	static String exe = "";

	static {
		try {
			docx = new java.io.File(".").getCanonicalPath()	+ "/files/docx_file";
			jpg = new java.io.File(".").getCanonicalPath() + "/files/jpg_file";
			odt = new java.io.File(".").getCanonicalPath() + "/files/open_office_odt_file";
			pdf = new java.io.File(".").getCanonicalPath() + "/files/pdf_file";
			exe = new java.io.File(".").getCanonicalPath() + "/files/prgrep_exe_file";

			files = new String[] { docx, jpg, odt, pdf, exe };
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static void testA() {
		ContentInfoUtil util = new ContentInfoUtil();
		try {
			ContentInfo info;

			for (int i = 0; i < files.length; i++) {
				info = util.findMatch(files[i]);
				if (info == null) {
					System.out.println(i + " Unknown content-type");
					continue;
				}

				System.out.println(i + " ContentType : " + info.getName());
				System.out.println(i + " MimeType : " + info.getMimeType());

				String[] extensions = info.getFileExtensions();
				if (extensions != null && extensions.length > 0) {
					for (int j = 0; j < extensions.length; j++) {
						System.out.println(i + " File Extension " + j + " : "
								+ extensions[j]);
					}
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static void testB() {
		MagicMatch match = null;

		try {
			for (int i = 0; i < files.length; i++) {
				match = Magic.getMagicMatch(new File(files[i]), true, false);

				if (match != null) {
					System.out.println(i + " File Ext  " + " : "
							+ match.getExtension());
					System.out.println(i + " File Mimetype  " + " : "
							+ match.getMimeType());
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {
		// testA();
		testB();
	}

}

프로젝트 다운로드 : FileFormatCheckTest.zip

답글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다.