Перейти к основному содержимому

Получение типа Mime файла в Java

· 4 мин. чтения

1. Обзор

В этом уроке мы рассмотрим различные стратегии получения MIME-типов файла. Мы рассмотрим способы расширения типов MIME, доступных для стратегий, где это применимо.

Мы также укажем, где мы должны предпочесть одну стратегию другой.

2. Использование Java 7

Начнем с Java 7, которая предоставляет метод Files.probeContentType(path) для разрешения типа MIME:

@Test
public void whenUsingJava7_thenSuccess() {
Path path = new File("product.png").toPath();
String mimeType = Files.probeContentType(path);

assertEquals(mimeType, "image/png");
}

Этот метод использует установленные реализации FileTypeDetector для проверки типа MIME. Он вызывает probeContentType каждой реализации для разрешения типа.

Теперь, если файл распознается любой из реализаций, возвращается тип содержимого. Однако, если этого не происходит, вызывается системный детектор типов файлов по умолчанию.

Однако реализации по умолчанию зависят от ОС и могут дать сбой в зависимости от используемой ОС.

В дополнение к этому также важно отметить, что стратегия потерпит неудачу, если файл отсутствует в файловой системе. Кроме того, если файл не имеет расширения, это приведет к ошибке.

3. Использование URLConnection

URLConnection предоставляет несколько API для определения типов файлов MIME. Кратко рассмотрим каждый из них.

3.1. Использование getContentType()

Мы можем использовать метод getContentType() URLConnection для получения 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. Использование предположенияContentTypeFromName()

Далее, давайте посмотрим, как мы можем использовать методgueContentTypeFromName() для этой цели:

@Test
public void whenUsingGuessContentTypeFromName_thenSuccess(){
File file = new File("product.png");
String mimeType = URLConnection.guessContentTypeFromName(file.getName());

assertEquals(mimeType, "image/png");
}

Этот метод использует внутреннюю FileNameMap для разрешения типа MIME из расширения .

У нас также есть возможность использовать вместо этого методgueContentTypeFromStream() , который использует первые несколько символов входного потока для определения типа.

3.3. Использование getFileNameMap ()

Более быстрый способ получить тип MIME с помощью URLConnection — использовать метод 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. Затем эта таблица используется для определения типа входного файла.

Встроенная таблица типов MIME очень ограничена, когда речь идет о URLConnection .

По умолчанию класс использует `` файл content-types.properties в JRE_HOME /lib . Однако мы можем расширить его, указав пользовательскую таблицу с помощью свойства content.types.user.table :

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 в качестве параметра внутренне вызывает перегруженный метод, который принимает имя файла в качестве параметра.

Внутри этот метод ищет разрешение типа в файле с именем mime.types . Очень важно отметить, что метод ищет файл в определенном порядке:

  1. Программно добавленные записи в экземпляр MimetypesFileTypeMap
  2. . mime.types в домашнем каталоге пользователя
  3. <java.home>/lib/mime.types
  4. ресурсы с именем META-INF/mime.types
  5. ресурс с именем META-INF/mimetypes.default (обычно находится только в файле активации.jar )

Однако, если файл не найден, он вернет application/octet-stream в качестве ответа.

5. Использование jMimeMagic

jMimeMagic — это библиотека с ограниченной лицензией, которую мы можем использовать для получения MIME-типа файла.

Начнем с настройки зависимости Maven:

<dependency>
<groupId>net.sf.jmimemagic</groupId>
<artifactId>jmimemagic</artifactId>
<version>0.1.5</version>
</dependency>

Мы можем найти последнюю версию этой библиотеки на 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 и поставляется с tika-core , который мы можем использовать для определения MIME-типа файла.

Начнем с настройки зависимости 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 .