JavaでファイルのMIMEタイプを取得する
1概要
このチュートリアルでは、ファイルのMIMEタイプを取得するためのさまざまな戦略を見ていきます。必要に応じて、利用可能なMIMEタイプを戦略に拡張する方法を検討します。
一方の戦略を他方の戦略よりも優先させるべき場所についても指摘します。
2 Java 7
を使う
Java 7から始めましょう – メソッドはhttps://docs.oracle.com/javase/7/docs/api/java/nio/file/Files.html#probeContentType%28java.nio.file.Path%29[MIMEタイプを解決するための
Files.probeContentType(path)
]
@Test
public void whenUsingJava7__thenSuccess() {
Path path = new File("product.png").toPath();
String mimeType = Files.probeContentType(path);
assertEquals(mimeType, "image/png");
}
このメソッドは、インストールされた
FileTypeDetector
実装を利用してMIMEタイプを調べます。型を解決するために各実装の
probeContentType
を呼び出します。
現在、ファイルがいずれかの実装によって認識されている場合は、コンテンツタイプが返されます。ただし、それが起こらない場合は、システムデフォルトのファイルタイプ検出機能が呼び出されます。
ただし、デフォルトの実装はOSによって異なり、使用しているOSによっては失敗する可能性があります。
それに加えて、ファイルがファイルシステムに存在しない場合、戦略が失敗することに注意することも重要です。さらに、ファイルに拡張子が付いていない場合は失敗します。
3.
URLConnection
を使う
URLConnection
は、ファイルのMIMEタイプを検出するためのいくつかのAPIを提供します。それぞれを簡単に調べてみましょう。
3.1.
getContentType()
を使用する
ファイルのMIMEタイプを取得するには、
URLConnection
の
getContentType()
メソッドを使用できます。
@Test
public void whenUsingGetContentType__thenSuccess(){
File file = new File("product.png");
URLConnection connection = file.toURL().openConnection();
String mimeType = connection.getContentType();
assertEquals(mimeType, "image/png");
}
ただし、このアプローチの大きな欠点は、** 非常に遅いことです。
3.2.
guessContentTypeFromName()
を使用する
次に、
guessContentTypeFromName()
を目的に使用する方法を見てみましょう。
@Test
public void whenUsingGuessContentTypeFromName__thenSuccess(){
File file = new File("product.png");
String mimeType = URLConnection.guessContentTypeFromName(file.getName());
assertEquals(mimeType, "image/png");
}
このメソッドは内部の
FileNameMap
を利用して** 拡張子からMIMEタイプを解決します。
代わりに
guessContentTypeFromStream()
を使用するオプションもあります。これは、入力ストリームの最初の数文字を使用してタイプを決定するためです。
3.3.
getFileNameMap
()
を使用する
URLConnection
を使用してMIMEタイプを取得するより早い方法は、
getFileNameMap()
メソッドを使用することです。
@Test
public void whenUsingGetFileNameMap__thenSuccess(){
File file = new File("product.png");
FileNameMap fileNameMap = URLConnection.getFileNameMap();
String mimeType = fileNameMap.getContentTypeFor(file.getName());
assertEquals(mimeType, "image/png");
}
このメソッドは、__URLConnectionのすべてのインスタンスで使用されるMIMEタイプのテーブルを返します。このテーブルは、入力ファイルタイプを解決するために使用されます。
MIMEタイプの組み込みテーブルは
URLConnection
に関しては非常に限られています。
デフォルトでは、
クラスは
JRE
HOME/lib
にある
content-types.properties
ファイルを使用します。 ** ただし、
content.types.user.table
__propertyを使用してユーザー固有のテーブルを指定することで拡張できます。
System.setProperty("content.types.user.table","<path-to-file>");
4
MimeTypesFileTypeMap
を使用する
MimeTypesFileTypeMap
は、ファイルの拡張子を使ってMIMEタイプを解決します。
このクラスはJava 6に付属しているので、JDK 1.6で作業するときに非常に便利です。
それでは、使い方を見てみましょう。
@Test
public void whenUsingMimeTypesFileTypeMap__thenSuccess() {
File file = new File("product.png");
MimetypesFileTypeMap fileTypeMap = new MimetypesFileTypeMap();
String mimeType = fileTypeMap.getContentType(file.getName());
assertEquals(mimeType, "image/png");
}
ここでは、ファイルの名前または
File
インスタンス自体を関数のパラメータとして渡すことができます。ただし、
File
インスタンスをパラメータとして持つ関数は、ファイル名をパラメータとして受け入れるオーバーロードされたメソッドを内部的に呼び出します。
-
内部的には、このメソッドは
mime.types
という名前のファイルを検索して型を解決します。メソッドが特定の順序でファイルを検索することに注意することは非常に重要です。**-
MimetypesFileTypeMap
インスタンスにプログラムで追加されたエントリ -
ユーザーのホームディレクトリにある.
mime.types
-
<java.home>/lib/mime.types
-
META-INF/mime.types
という名前のリソース -
META-INF/mimetypes.default
という名前のリソース(通常は
-
activation.jar
ファイル)
ただし、ファイルが見つからない場合は、応答として
application/octet-stream
が返されます。
5 jMimeMagic
を使う
jMimeMagic
は、ファイルのMIMEタイプを取得するために使用できる制限付きライセンスライブラリです。
Mavenの依存関係を設定することから始めましょう:
<dependency>
<groupId>net.sf.jmimemagic</groupId>
<artifactId>jmimemagic</artifactId>
<version>0.1.5</version>
</dependency>
このライブラリの最新版はhttps://search.maven.org/classic/#search%7C1%7Cg%3A%22net.sf.jmimemagic%22%20AND%20a%3A%22jmimemagic%22にあります。[Maven Central]
次に、図書館の利用方法を探ります。
@Test
public void whenUsingJmimeMagic__thenSuccess() {
File file = new File("product.png");
Magic magic = new Magic();
MagicMatch match = magic.getMagicMatch(file, false);
assertEquals(match.getMimeType(), "image/png");
}
このライブラリは一連のデータを扱うことができるので、ファイルがファイルシステムに存在する必要はありません。
6. Apache Tika
を使う
Apache Tika
は、さまざまなファイルからメタデータとテキストを検出して抽出するツールセットです。それは豊富で強力なAPIを持ち、https://search.maven.org/classic/#search%7C1%7Cg%3A%22org.apache.tika%22%20AND%20a%3A%22tika-coreが付属ファイルのMIMEタイプを検出するために利用可能な%22[tika-core]。
Mavenの依存関係を設定することから始めましょう:
<dependency>
<groupId>org.apache.tika</groupId>
<artifactId>tika-core</artifactId>
<version>1.18</version>
</dependency>
次に、
detect()
メソッドを使って型を解決します。
@Test
public void whenUsingTika__thenSuccess() {
File file = new File("product.png");
Tika tika = new Tika();
String mimeType = tika.detect(file);
assertEquals(mimeType, "image/png");
}
このライブラリは、型解決のためにストリームプレフィックス内のマジックマーカーに依存しています。
7. 結論
この記事では、ファイルのMIMEタイプを取得するためのさまざまな戦略について説明しました。さらに、アプローチのトレードオフについても分析しました。一方の戦略を他方の戦略よりも優先させるべきシナリオについても指摘しました。
この記事で使用されている完全なソースコードはhttps://github.com/eugenp/tutorials/tree/master/core-java[over at GitHub]から入手できます。