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

Мне просто интересно, как большинство людей извлекают MIME-тип из файла на Java? Пока что пробовал две утилиты: JMimeMagic и Mime-Util.

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

Хороший обзор доступных библиотек можно найти на rgagnon.com/javadetails/java-0487.html.

koppor 18.05.2013 02:15

Я использовал класс, который был размещен здесь в качестве ответа: stackoverflow.com/a/10140531/293280

Joshua Pinter 18.03.2014 11:57

Теперь ответом должна быть Тика. Другие ответы ниже освещают многие зависимости от Tika, но я не вижу их с tika-core.

javamonkey79 14.12.2015 18:51

@ javamonkey79, когда мы используем TIka, он закрывает файл, и его больше нельзя использовать. String contentType = tika.detect (is).

Cool Techie 27.03.2017 08:57
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
344
4
407 584
25
Перейти к ответу Данный вопрос помечен как решенный

Ответы 25

К несчастью,

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 (отличная библиотека, использующая как расширение файла, так и содержимое).

Отличное решение - мне очень помогло! Обертывание FileInputStream в BufferedInputStream является важной частью - иначе guessContentTypeFromStream вернет null (переданный экземпляр InputStream должен поддерживать метки)

Yuriy Nakonechnyy 09.11.2012 15:09

Однако URLConnection имеет очень ограниченный набор типов контента, которые он распознает. Например, он не может обнаружить application/pdf.

kpentchev 17.07.2013 12:25

@kpentchev он обнаруживает pdf для меня. Но он не обнаруживает офисные файлы, например * .doc

FeinesFabi 12.03.2014 15:57

Он остается заблокированным только потому, что вы не оставили себе возможности закрыть его. Отключение URLConnection разблокирует его.

user207421 02.05.2014 04:00

как guessContentTypeFromStream, так и guessContentTypeFromName НЕ распознают, например. mp4

Hartmut Pfarr 29.07.2015 20:42

guessContentTypeFromName() использует файл $JAVA_HOME/lib/content-types.properties по умолчанию. вы можете добавить свой собственный расширенный файл, изменив системное свойство System.setProperty("content.types.user.table","/lib/path/to/‌​your/property/file")‌​;

Rasika Perera 30.08.2015 08:55

Он не обнаруживает файлы .js, .css. Есть ли другой способ обнаружить эти файлы?

vjnan369 25.01.2017 15:09

Есть ссылки на Mime-Util ??? Я нашел проект в github, но он не содержит описания :(

Cherry 13.10.2017 17:07

guessContentTypeFromName использует этот synchronized FileNameMap getFileNameMap удачи в многопоточности

best wishes 09.06.2018 13:11

JAF API является частью JDK 6. Посмотрите на пакет javax.activation.

Наиболее интересными классами являются 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);

К сожалению, как указано в javadoc для getContentType(File): Возвращает MIME-тип файлового объекта. Реализация в этом классе вызывает getContentType(f.getName()).

Matyas 24.10.2011 18:27

И помните, что вы можете расширить эту функциональность с помощью файла META-INF / mime.types, поэтому он идеален, если вы вынуждены использовать Java 6. docs.oracle.com/javaee/5/api/javax/activation/…

Chexpir 23.01.2014 15:12

вы можете пропустить создание нового объекта с помощью MimetypesFileTypeMap.getDefaultFileTypeMap().getContentType(‌​file)

akostadinov 23.02.2015 12:21

Спасибо за Ваш ответ. У меня это успешно работает.

Radadiya Nikunj 15.08.2018 21:28

Но он по-прежнему возвращает тип содержимого только на основе имени файла. А это особенно опасно для файлов, загружаемых пользователями.

Sergey Ponomarev 05.02.2019 23:40

Это не работает, например, для файлов pdf (возвращается application/octet-stream).

Dmitriy Popov 10.09.2020 14:59

От розаиндия:

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

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

AlikElzin-kilaka 24.06.2013 16:35

Я не голосовал за вас, но getFileNameMap не работает для многих базовых типов файлов, например «bmp». Также URLConnection.guessContentTypeFromName возвращает то же самое

Ovidiu Buligan 05.09.2013 18:39

Очень неполная функция. Начиная с Java 7, расширения html, pdf и jpeg возвращают правильный mime-тип, но js и css возвращают null!

djsumdog 29.04.2014 13:30

Я тестировал с помощью «webm», и он вернул ноль.

Henrique Rocha 22.08.2016 17:42
Ответ принят как подходящий

В Java 7 теперь можно просто использовать Files.probeContentType(path).

Это было очень полезно, поскольку веб-сайт mime-util, похоже, не работает, и я не могу сказать, поддерживается ли вообще библиотека!

Jazzepi 18.07.2012 00:48

Это работает хорошо, однако я не нашел способа добавить другие типы файлов, которые я понимаю. Например, образ ISO возвращает null, как и архив .zip, и даже файл конфигурации ini.

ldam 18.12.2012 15:00

Это прекрасное.

james.garriss 26.07.2013 23:23

@ james.garriss, и он принес мне больше очков, чем любой другой ответ, который я когда-либо давал! Сумасшедший, да? :)

Chris Mowforth 27.07.2013 03:49

Имейте в виду, что Files.probeContentType (Path) содержит ошибки в нескольких операционных системах, и было отправлено множество отчетов об ошибках. У меня была проблема с программным обеспечением, работающим на ubuntu, но не работающим на Windows. Казалось, что в Windows Files.probeContentType (Path) всегда возвращал null. Это была не моя система, поэтому я не проверял версию JRE или Windows. Это были Windows 7 или 8, вероятно, с Oracle JRE для Java 7.

Silver 22.11.2013 00:31

Я работаю на OS X 10.9 и получаю null для файлов .xml, .png и .xhtml. Не знаю, делаю ли я что-то ужасно неправильно, но это кажется ужасным.

user372743 27.02.2014 18:59

Мне не удалось заставить это работать успешно, если файл не имеет расширения.

JoshDM 23.09.2014 22:42

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

Thomas Jung 21.02.2015 20:12

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

Necreaux 31.03.2015 21:06

Что еще более странно, у меня есть два ноутбука с Windows 8.1, один из которых получает application/x-zip-compressed, а другой - null в результате вызова этого в zip-файле. Совершенно ненадежно: \. Итак, учитывая, что я хочу, чтобы мое приложение включало схему кодирования файла (допустим, мое приложение принимает конфигурацию как XML, так и JSON), а файл просто называется «конфигурацией» (без расширения), это самый надежный способ определить тип этого файла, обман и чтение нескольких байтов?

Groostav 04.07.2015 02:28

этот метод не может возвращать тип mime, когда я удаляю расширение из имени. Например, если имя test.mp4, я меняю его на «test», и метод возвращает null. Также я меняю расширение фильма на png и т. д. он возвращает тип mime png

Sarkhan 04.06.2016 22:08

Это бесполезно, если у файла отсутствует или неправильное расширение.

shmosel 16.07.2016 01:11

Реализация на основе Linux, похоже, использует Linux / usr / bin / file, что хорошо, если нет расширения, которому он просто верит, не глядя глубже, что плохо. Если вы переименуете XML-файл в .json, это скажет вам, что это JSON. Мусор на входе, мусор на выходе. Вы просто не хотите доверять этому подходу, если вы не уверены в своих файловых данных.

Russ Bateman 19.07.2016 19:34

@RussBateman unless there's an extension, which it just believes without looking deeper, which is bad. Делают ли nginx / apache и т. д. Больше, чем просто смотрят на расширение?

elhefe 02.02.2017 22:35

Этот метод плохой, он отключается от расширения, не беспокоится о магическом числе и возвращает null в разных системах ... даже с той же ОС. Был обманут и не могу рекомендовать. Вы также можете просто сравнить расширение файла.

romulusnr 24.03.2020 23:15

А чтобы получить Path от String, используйте Paths.get(str).

Holger L 14.10.2020 14:09

В Windows для определения типа файла используются только расширения. В Linux до Java 8 использовалось множество детекторов: детекторы на основе содержимого, основанные на библиотеках Gnome I / O, Gnome VFS и libmagic, а также на основе расширений, реализованных на /etc/mime.types. Но начиная с Java9 все детекторы на основе содержимого были удалены из JDK (12), а для Linux остались только детекторы на основе расширений. Поэтому, если у вашего файла нет расширения, этот метод всегда будет возвращать null :(

And-y 04.03.2021 07:05

Я пробовал несколько способов сделать это, в том числе первый, который сказал @Joshua Fox. Но некоторые не распознают частые mimetypes, например, для файлов 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();

У меня вообще не было успеха с MimeUtil2 - почти все возвращалось как application / octet-stream. Я использовал MimeUtil.getMimeTypes () с гораздо большим успехом после инициализации с помощью `MimeUtil.registerMimeDetector (" eu.medsea.mimeutil.detector.M‌ agicMimeMimeDetector‌ "); MimeUtil.registerMimeDetector ("eu.medsea.mimeutil.detector.E‌ xtensionMimeDetector‌"); MimeUtil.registerMimeDetector ("eu.medsea.mimeutil.detector.O‌ pendesktopMimeDetect‌ или"); `

Brian Pipa 11.12.2012 22:45

Спасибо за рабочее решение. В документации mime-util не очень ясно, как создать экземпляр служебного класса. Наконец он заработал, но заменил строку имени класса фактическим классом. MimeUtil.registerMimeDetector (ExtensionMimeDetector.class.ge‌ tName ()); String mimeType = MimeUtil.getMostSpecificMimeType (MimeUtil.getMimeTypes (filen file ame)). ToString ();

Rob Juurlink 01.02.2013 02:28

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

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

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

Это также работает, если попытаться использовать локальные пути к файлам, такие как "/sdcard/path/to/video.extension". Проблема в том, что если локальный файл содержит пробел на своем пути, он всегда возвращает null

nmxprime 31.12.2015 08:11

Апач Тика предлагает в тика-ядро определение типа 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(...) нельзя использовать напрямую (ТИКА-1120). Дополнительные подсказки представлены в https://tika.apache.org/1.24/detection.html.

+1 Также Metadata.RESOURCE_NAME_KEY можно не указывать (если у вас его нет или вы не можете полагаться на оригинальное имя), но в этом случае вы получите неверный результат в некоторых случаях (например, в офисных документах).

user1516873 17.04.2017 17:20

У него есть некоторые проблемы с обнаружением XLSX, если для имени файла нет расширения ... но это решение простое и элегантное.

Oscar Pérez 04.01.2018 15:47

I was just wondering how most people fetch a mime type from a file in Java?

Я опубликовал свой пакет Java SimpleMagic, который позволяет определять тип содержимого (тип mime) из файлов и массивов байтов. Он предназначен для чтения и запуска командных магических файлов файла Unix (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();
}

Протестировал на нескольких файлах изображений. Все расширения переименованы. Ваша замечательная библиотека справилась с этим должным образом. Конечно, тоже свет :).

saurabheights 12.08.2016 17:22

Да, это хорошо работает. А для тех, кому нужно использовать это решение в Android, вы можете просто включить в файл build.gradle следующее: compile ('com.j256.simplemagic: simplemagic: 1.10')

jkincali 20.02.2017 16:12

Это отличное решение! Спасибо!

javydreamercsw 12.07.2017 18:52

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

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

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

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

Работал с простыми, популярными и немногими нужными мне типами файлов :)

user489041 21.12.2016 21:23

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

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

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

если вы работаете в ОС 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'

Это будет работать, но IMO - плохая практика, поскольку он связывает ваш код с конкретной ОС и требует, чтобы внешняя утилита присутствовала в системе, в которой она запущена. Не поймите меня неправильно; это полностью действующее решение, но оно нарушает переносимость - что является одной из основных причин использовать Java в первую очередь ...

ToVine 18.10.2015 20:43

@ToVine: Для протокола, я с уважением не согласен. Не каждая программа на Java обязана быть переносимой. Позвольте контексту и программисту принять это решение. en.wikipedia.org/wiki/Java_Native_Interface

EmpathicSage 26.08.2018 22:56

весной файл MultipartFile;

org.springframework.web.multipart.MultipartFile

file.getContentType();

Попробовав различные другие библиотеки, я остановился на 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);

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

Этот метод Files.probeContentType (String) доступен, начиная с версии JDK 1.7, и у меня он очень хорошо работает.

Reza Rahimi 30.11.2017 14:30

Спасибо, только я не могу понять, почему некоторые пользователи проголосовали против)))

Vazgen Torosyan 30.11.2017 23:23

Совсем нет, может у них более ранняя версия JDK :)))

Reza Rahimi 01.12.2017 15:54

С Апач Тика вам понадобится только три строки кода:

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-интерфейсы богаты, он может разбирать «все». Начиная с tika-core 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)

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

Это не работает для csv. wtf? stackoverflow.com/questions/46960231/…

gstackoverflow 26.10.2017 20:24

Одна плохая вещь в Тике - множество зависимостей. Это увеличило размер моей банки на 54 МБ !!!

helmy 22.11.2017 21:48

@helmyTika 1.17 является автономным и имеет размер всего 648 КБ.

Sainan 22.01.2018 17:21

... или просто new Tika().detect(file.toPath()) для обнаружения на основе расширения файла, а не обнаружения на основе содержимого файла

Lu55 05.06.2018 13:59

Документы @ Lu55 говорят, что по-прежнему использует содержимое документа. Я думаю, вы имеете в виду new Tika().detect(file.getPath()), который использует только расширение файла

delucasvb 29.06.2018 13:31

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

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

Отличное решение!

Sherzod 28.01.2020 16:54

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

TL, DR

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

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

Прежде всего, список типов 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.probeContentType(Paths.get("either file name or full path goes here"));

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

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

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

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

Вы можете сделать это с помощью одной строки: MimetypesFileTypeMap (). GetContentType (новый файл ("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")));
    }
}

Этот код дает следующий результат: текст / простой

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

Хотя этот код может решить вопрос, включая объяснение действительно помогает улучшить качество вашего сообщения.

Shree 17.05.2019 13:51

Я сделал это с помощью следующего кода.

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

public class MimeFileType {

    public static void main(String args[]){

        try{
            URL url = new URL ("https://www.url.com.pdf");

            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("GET");
            connection.setDoOutput(true);
            InputStream content = (InputStream)connection.getInputStream();
            connection.getHeaderField("Content-Type");

            System.out.println("Content-Type "+ connection.getHeaderField("Content-Type"));

            BufferedReader in = new BufferedReader (new InputStreamReader(content));

        }catch (Exception e){

        }
    }
}

Если вы работаете с сервлетом и вам доступен контекст сервлета, вы можете использовать:

getServletContext().getMimeType( fileName );

Что такое getServletContext?

e-info128 30.04.2020 07:40

Апач Тика.

<!-- https://mvnrepository.com/artifact/org.apache.tika/tika-parsers -->
<dependency>
    <groupId>org.apache.tika</groupId>
    <artifactId>tika-parsers</artifactId>
    <version>1.24</version>
</dependency>

и две строки кода.

Tika tika=new Tika();
tika.detect(inputStream);

Снимок экрана ниже

Мне не удалось найти ничего для проверки типа MIME video/mp4, поэтому я сделал собственное решение. Я случайно заметил, что Википедия ошибалась и что подпись файла 00 00 00 18 66 74 79 70 69 73 6F 6D неверна. четвертый байт (18) и все 70 (исключенные) после значительных изменений среди других допустимых файлов mp4.

Этот код по сути является копией / вставкой кода URLConnection.guessContentTypeFromStream, но адаптирован для video/mp4.

BufferedInputStream bis = new BufferedInputStream(new ByteArrayInputStream(content));
String mimeType = URLConnection.guessContentTypeFromStream(bis);

// Goes full barbaric and processes the bytes manually
if (mimeType == null){
    // These ints converted in hex ar:
    // 00 00 00 18 66 74 79 70 69 73 6F 6D
    // which are the file signature (magic bytes) for .mp4 files
    // from https://www.wikiwand.com/en/List_of_file_signatures
    // just ctrl+f "mp4"
    int[] mp4_sig = {0, 0, 0, 24, 102, 116, 121, 112};

    bis.reset();
    bis.mark(16);
    int[] firstBytes = new int[8];
    for (int i = 0; i < 8; i++) {
        firstBytes[i] = bis.read();
    }
    // This byte doesn't matter for the file signature and changes
    mp4_sig[3] = content[3];

    bis.reset();
    if (Arrays.equals(firstBytes, mp4_sig)){
        mimeType = "video/mp4";
    }
}

Успешно протестирован с 10 различными файлами .mp4.

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

Простой и лучший вариант - получить тип MIME содержимого из местоположения файла.

Используйте этот импорт

import java.nio.file.Files;
import java.nio.file.Path;

Код

String type = Files.probeContentType(Path.of(imagePath));

Потому что так много ответов, связанных с библиотеками или непереносимым кодом; Я подумал, что поделюсь альтернативным способом, просто проверив магические байты потока или файла, тип которого вы хотите узнать, как я показал здесь: https://stackoverflow.com/a/65667558/3225638

Он использует родную java, но требует, чтобы вы заранее определили в перечислении типы, которые вы хотите обрабатывать / обнаруживать, но вам нужно будет сделать это только один раз.

Другие вопросы по теме