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

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

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

Однако основным недостатком этого подхода является то, чтоit’s very slow.

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 доresolve the MIME type from the extension.

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

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.

По умолчанию файлthe class uses content-types.properties вJRE_HOME/lib. We can, however, extend it, by specifying a user-specific table using the content.types.user.table property:

System.setProperty("content.types.user.table","");

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 для разрешения типа. Очень важно отметить, что метод ищет файл в определенном порядке:

  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:


    net.sf.jmimemagic
    jmimemagic
    0.1.5

Мы можем найти последнюю версию этой библиотеки на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:


    org.apache.tika
    tika-core
    1.18

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

Полный исходный код, который используется в этой статье, как всегда доступенover at GitHub.