1. 概要

このチュートリアルでは、ファイルのMIMEタイプを取得するためのさまざまな戦略を見ていきます。 該当する場合は、戦略で使用可能なMIMEタイプを拡張する方法を検討します。

また、ある戦略を他の戦略よりも優先すべき場所についても指摘します。

2. Java7の使用

Java 7から始めましょう–これは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()の使用

URLConnectiongetContentType()メソッドを使用して、ファイルのMIMEタイプを取得できます。

@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");
}

このメソッドは、のすべてのインスタンスで使用されるMIMEタイプのテーブルを返します。 URLConnection。 このテーブルは、入力ファイルタイプを解決するために使用されます。

URLConnection に関しては、MIMEタイプの組み込みテーブルは非常に制限されています。

デフォルトでは、クラスは JRE_HOME /libのcontent-types.propertiesファイルを使用します。 ただし、content.types.user.tableプロパティを使用してユーザー固有のテーブルを指定することで拡張できます:

System.setProperty("content.types.user.table","<path-to-file>");

4. MimeTypesFileTypeMapを使用する

MimeTypesFileTypeMap は、ファイルの拡張子を使用してMIMEタイプを解決します。 このクラスにはJava6が付属しているため、JDK1.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と呼ばれるファイルを検索します。 このメソッドは特定の順序でファイルを検索することに注意することが非常に重要です。

  1. MimetypesFileTypeMapインスタンスにプログラムで追加されたエントリ
  2. ユーザーのホームディレクトリにある。mime.types
  3. /lib/mime.types
  4. META-INF /mime.typesという名前のリソース
  5. 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>

このライブラリの最新バージョンは、 MavenCentralにあります。

次に、ライブラリの操作方法について説明します。

@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. ApacheTikaを使用する

Apache Tika は、さまざまなファイルからメタデータとテキストを検出して抽出するツールセットです。 豊富で強力なAPIを備えており、ファイルのMIMEタイプを検出するために使用できる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タイプを取得するためのさまざまな戦略について説明しました。 さらに、アプローチのトレードオフも分析しました。 また、ある戦略を他の戦略よりも優先する必要があるシナリオも指摘しました。

この記事で使用されている完全なソースコードは、いつものようにGitHubから入手できます。