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

Мне просто интересно, как большинство людей выбирает тип mime из файла на Java? До сих пор я пробовал два utils: JMimeMagic и Mime-Util.

Первые дали мне исключения для памяти, вторая не закрывает свои потоки должным образом. Мне просто интересно, есть ли у кого-нибудь другой метод/библиотека, которые они использовали и работали правильно?

Ответ 2

К сожалению,

mimeType = file.toURL().openConnection().getContentType();

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

Однако у вас есть это:

mimeType= URLConnection.guessContentTypeFromName(file.getName());

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

InputStream is = new BufferedInputStream(new FileInputStream(file));
mimeType = URLConnection.guessContentTypeFromStream(is);
 //...close stream

Однако, как было предложено выше, встроенная таблица типов mime довольно ограничена, не включая, например, MSWord и PDF. Итак, если вы хотите обобщить, вам нужно выйти за рамки встроенных библиотек, используя, например, Mime-Util (это отличная библиотека, использующая как расширение файла, так и контент).

Ответ 3

API JAF является частью JDK 6. Посмотрите <. →

Наиболее интересными классами являются javax.activation.MimeType - фактический держатель типа MIME - и javax.activation.MimetypesFileTypeMap - класс, чей экземпляр может разрешить MIME-тип как String для файла:

String fileName = "/path/to/file";
MimetypesFileTypeMap mimeTypesMap = new MimetypesFileTypeMap();

// only by file name
String mimeType = mimeTypesMap.getContentType(fileName);

// or by actual File instance
File file = new File(fileName);
mimeType = mimeTypesMap.getContentType(file);

Ответ 4

С Apache Tika вам нужно всего три строчки кода:

File file = new File("/path/to/file");
Tika tika = new Tika();
System.out.println(tika.detect(file));

Если у вас отличная консоль, просто вставьте и запустите этот код, чтобы поиграть с ней:

@Grab('org.apache.tika:tika-core:1.14')
import org.apache.tika.Tika;

def tika = new Tika()
def file = new File("/path/to/file")
println tika.detect(file)

Имейте в виду, что его API-интерфейсы богаты, он может анализировать "что угодно". Начиная с версии 1.14, у вас есть:

String  detect(byte[] prefix)
String  detect(byte[] prefix, String name)
String  detect(File file)
String  detect(InputStream stream)
String  detect(InputStream stream, Metadata metadata)
String  detect(InputStream stream, String name)
String  detect(Path path)
String  detect(String name)
String  detect(URL url)

Смотрите apidocs для получения дополнительной информации.

Ответ 5

Apache Tika предлагает в tika-core mime типа, основанного на волшебных маркерах в префиксе потока. tika-core не извлекает другие зависимости, что делает его столь же легким, как и текущая потерянная Утилита обнаружения тисков Mime.

Простой пример кода (Java 7), используя переменные theInputStream и theFileName

try (InputStream is = theInputStream;
        BufferedInputStream bis = new BufferedInputStream(is);) {
    AutoDetectParser parser = new AutoDetectParser();
    Detector detector = parser.getDetector();
    Metadata md = new Metadata();
    md.add(Metadata.RESOURCE_NAME_KEY, theFileName);
    MediaType mediaType = detector.detect(bis, md);
    return mediaType.toString();
}

Обратите внимание, что MediaType.detect(...) нельзя использовать напрямую (TIKA-1120). Дополнительные советы предоставляются на https://tika.apache.org/0.10/detection.html.

Ответ 6

Если вы разработчик Android, вы можете использовать класс утилиты android.webkit.MimeTypeMap, который сопоставляет MIME-типы с расширениями файлов и наоборот.

Следующий фрагмент кода может вам помочь.

private static String getMimeType(String fileUrl) {
    String extension = MimeTypeMap.getFileExtensionFromUrl(fileUrl);
    return MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
}

Ответ 7

От roseindia:

FileNameMap fileNameMap = URLConnection.getFileNameMap();
String mimeType = fileNameMap.getContentTypeFor("alert.gif");

Ответ 8

Если вы застряли с Java 5-6, то этот служебный класс из серво продукта с открытым исходным кодом.

Вам нужна только эта функция

public static String getContentType(byte[] data, String name)

Он проверяет первые байты содержимого и возвращает типы содержимого на основе этого содержимого, а не по расширению файла.

Ответ 9

Мне было просто интересно, как большинство людей выбирают mime-тип из файла на Java?

Я опубликовал свой пакет Java SimpleMagic, который позволяет определять тип содержимого (mime-type) из файлов и байтовых массивов. Он предназначен для чтения и запуска магических файлов команд Unix file (1), которые являются частью большинства конфигураций ОС Unix.

Я попробовал Apache Tika, но он огромен с множеством зависимостей, URLConnection не использует байты файлов, а MimetypesFileTypeMap также просто смотрит на имена файлов.

С SimpleMagic вы можете сделать что-то вроде:

// create a magic utility using the internal magic file
ContentInfoUtil util = new ContentInfoUtil();
// if you want to use a different config file(s), you can load them by hand:
// ContentInfoUtil util = new ContentInfoUtil("/etc/magic");
...
ContentInfo info = util.findMatch("/tmp/upload.tmp");
// or
ContentInfo info = util.findMatch(inputStream);
// or
ContentInfo info = util.findMatch(contentByteArray);

// null if no match
if (info != null) {
   String mimeType = info.getMimeType();
}

Ответ 10

Чтобы скинуть мои 5 центов:

TL, DR

Я использую MimetypesFileTypeMap и добавляю в файл mime.types любой mime, которого там нет, и он мне особенно нужен.

А теперь долго читал:

Прежде всего, список типов MIME огромен, см. Здесь: https://www.iana.org/assignments/media-types/media-types.xhtml

Мне нравится сначала использовать стандартные возможности, предоставляемые JDK, и если это не сработает, я пойду и поищу что-нибудь еще.

Определить тип файла по расширению файла

Начиная с 1.6, Java имеет MimetypesFileTypeMap, как указано в одном из ответов выше, и это самый простой способ определить тип mime:

new MimetypesFileTypeMap().getContentType( fileName );

В его ванильной реализации это мало что делает (то есть работает для .html, но не для .png). Однако очень просто добавить любой тип контента, который вам может понадобиться:

  1. Создайте файл с именем "mime.types" в папке META-INF в вашем проекте
  2. Добавьте строку для каждого типа MIME, который вам нужен, и реализация по умолчанию не обеспечивает (существуют сотни типов MIME, и список увеличивается с течением времени).

Пример записи для файлов png и js:

image/png png PNG
application/javascript js

Подробнее о формате файла mime.types см. Здесь: https://docs.oracle.com/javase/7/docs/api/javax/activation/MimetypesFileTypeMap.html.

Определить тип файла из содержимого файла

Начиная с 1.7, Java имеет java.nio.file.spi.FileTypeDetector, который определяет стандартный API для определения типа файла специфичным для реализации способом.

Чтобы получить mime-тип для файла, вы просто должны использовать Files и сделать это в своем коде:

Files.probeContentType(Paths.get("either file name or full path goes here"));

Определение API предоставляет средства, которые поддерживают либо определение типа mime файла по имени файла, либо по содержимому файла (волшебные байты). Вот почему метод probeContentType() выбрасывает IOException, если реализация этого API использует предоставленный ему Path, чтобы фактически попытаться открыть связанный с ним файл.

Опять же, ванильная реализация этого (того, что идет с JDK) оставляет желать лучшего.

В каком-то идеальном мире в далекой-далекой галактике все эти библиотеки, которые пытаются решить эту проблему типа "файл-пантомима", просто реализуют java.nio.file.spi.FileTypeDetector, вы можете оставить предпочтительный jar библиотеки реализации файл в ваш путь к классу, и это было бы так.

В реальном мире, где вам нужен раздел TL, DR, вы должны найти библиотеку с большинством звездочек рядом с ее именем и использовать ее. Для этого конкретного случая мне не нужен один (пока;)).

Ответ 11

Я попробовал несколько способов сделать это, в том числе первые, которые сказал @Joshua Fox. Но некоторые из них не распознают частые миметики, например, для файлов PDF, а другие не могут быть надежными с поддельными файлами (я пытался с RAR файлом с расширением, измененным на TIF). Решение, которое я нашел, также, по словам @Joshua Fox, поверхностным образом заключается в использовании MimeUtil2, например:

MimeUtil2 mimeUtil = new MimeUtil2();
mimeUtil.registerMimeDetector("eu.medsea.mimeutil.detector.MagicMimeMimeDetector");
String mimeType = MimeUtil2.getMostSpecificMimeType(mimeUtil.getMimeTypes(file)).toString();

Ответ 12

Лучше использовать проверку двух уровней для загрузки файлов.

Сначала вы можете проверить mimeType и проверить его.

Во-вторых, вы должны преобразовать первые 4 байта вашего файла в шестнадцатеричный, а затем сравнить его с магическими числами. Тогда это будет действительно безопасный способ проверить проверки файлов.

Ответ 13

в файле spring MultipartFile;

org.springframework.web.multipart.MultipartFile

file.getContentType();

Ответ 14

Это самый простой способ, который я нашел для этого:

byte[] byteArray = ...
InputStream is = new BufferedInputStream(new ByteArrayInputStream(byteArray));
String mimeType = URLConnection.guessContentTypeFromStream(is);

Ответ 15

если вы работаете с операционной системой Linux, есть командная строка file --mimetype:

String mimetype(file){

   //1. run cmd
   Object cmd=Runtime.getRuntime().exec("file --mime-type "+file);

   //2 get output of cmd , then 
    //3. parse mimetype
    if(output){return output.split(":")[1].trim(); }
    return "";
}

Тогда

mimetype("/home/nyapp.war") //  'application/zip'

mimetype("/var/www/ggg/au.mp3") //  'audio/mp3'

Ответ 16

Попробовав различные библиотеки, я установил mime-util.

<groupId>eu.medsea.mimeutil</groupId>
      <artifactId>mime-util</artifactId>
      <version>2.1.3</version>
</dependency>

File file = new File("D:/test.tif");
MimeUtil.registerMimeDetector("eu.medsea.mimeutil.detector.MagicMimeMimeDetector");
Collection<?> mimeTypes = MimeUtil.getMimeTypes(file);
System.out.println(mimeTypes);

Ответ 17

public String getFileContentType(String fileName) {
    String fileType = "Undetermined";
    final File file = new File(fileName);
    try
    {
        fileType = Files.probeContentType(file.toPath());
    }
    catch (IOException ioException)
    {
        System.out.println(
                "ERROR: Unable to determine file type for " + fileName
                        + " due to exception " + ioException);
    }
    return fileType;
}

Ответ 18

Вы можете сделать это всего одной строкой: MimetypesFileTypeMap(). GetContentType (new File ("filename.ext")). Посмотрите полный тестовый код (Java 7):

import java.io.File;
import javax.activation.MimetypesFileTypeMap;
public class MimeTest {
    public static void main(String a[]){
         System.out.println(new MimetypesFileTypeMap().getContentType(
           new File("/path/filename.txt")));
    }
}

Этот код производит следующий вывод: text/plain

Ответ 19

File file = new File(PropertiesReader.FILE_PATH);
MimetypesFileTypeMap fileTypeMap = new MimetypesFileTypeMap();
String mimeType = fileTypeMap.getContentType(file);
URLConnection uconnection = file.toURL().openConnection();
mimeType = uconnection.getContentType();