Получение типа Mime файла в Java
мне просто интересно, как большинство людей получают тип mime из файла в Java? До сих пор я пробовал два utils:JMimeMagic & Mime-Util.
первый дал мне исключения памяти, второй не закрывает свои потоки должным образом. Мне просто интересно, есть ли у кого-нибудь еще метод/библиотека, которые они использовали и работали правильно?
18 ответов:
в Java 7, Теперь вы можете просто использовать
Files.probeContentType(path).
к сожалению,
mimeType = file.toURL().openConnection().getContentType();не работает, так как это использование URL-адреса оставляет файл заблокированным, так что, например, он является undeletable.
, у вас есть это:mimeType= URLConnection.guessContentTypeFromName(file.getName());а также следующее, что имеет преимущество выхода за рамки простого использования расширения файла, и заглядывает в содержимое
InputStream is = new BufferedInputStream(new FileInputStream(file)); mimeType = URLConnection.guessContentTypeFromStream(is); //...close streamоднако, как было предложено в комментарии выше, встроенная таблица MIME-типов довольно ограничена, не включая, например, MSWord и PDF. Итак, если вы хотите обобщить, вам нужно будет выйти за рамки встроенных библиотек, используя, например, Mime-Util (который является отличной библиотекой, используя как расширение файла, так и контент).
API JAF является частью JDK 6. Посмотри на
javax.activationпакета.самые интересные классы
javax.activation.MimeType- фактический держатель типа MIME-иjavax.activation.MimetypesFileTypeMap- класс, экземпляр которого может разрешить тип MIME как строку для файла: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);
С 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 богаты, он может анализировать "что угодно". По состоянию на 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)посмотреть в apidocs для получения дополнительной информации.
Apache Tika предложения тика-ядро обнаружение типа mime на основе магических маркеров в префиксе потока.
tika-coreне извлекает другие зависимости, что делает его таким же легким, как и в настоящее время unmaintained Утилита Обнаружения Типа Mime.простой пример кода (Java 7), используя переменные
theInputStreamиtheFileNametry (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.обнаруживать.(..) не может использоваться непосредственно (тика-1120). Дополнительные подсказки предоставляются по адресу https://tika.apache.org/0.10/detection.html.
Если вы разработчик Android, вы можете использовать класс утилиты
android.webkit.MimeTypeMapкоторый сопоставляет MIME-типы с расширениями файлов и наоборот.следующий фрагмент кода может помочь вам.
private static String getMimeType(String fileUrl) { String extension = MimeTypeMap.getFileExtensionFromUrl(fileUrl); return MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension); }
С roseindia:
FileNameMap fileNameMap = URLConnection.getFileNameMap(); String mimeType = fileNameMap.getContentTypeFor("alert.gif");
Если вы застряли с java 5-6 тогда это утилита класса от servoy open source product
вам нужна только эта функция
public static String getContentType(byte[] data, String name)он проверяет первые байты содержимого и возвращает типы содержимого на основе этого содержимого, а не по расширению файла.
мне просто интересно, как большинство людей получают тип mime из файла в Java?
я опубликовал SimpleMagic пакет Java, который позволяет определять тип контента (mime-тип) из файлов и байтовых массивов. Он предназначен для чтения и запуска файлов Unix (1)command magic, которые являются частью большинства конфигураций ОС ~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(); }
я попробовал несколько способов сделать это, в том числе первые из них сказал @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();
для загрузки файлов лучше использовать двухслойную проверку.
сначала вы можете проверить тип mimeType и проверить его.
во-вторых, вы должны посмотреть, чтобы преобразовать первые 4 байта вашего файла в шестнадцатеричный, а затем сравнить его с магическими числами. Тогда это будет действительно безопасный способ проверить проверку файлов.
чтобы скинуться с моими 5 центов:
TL, DR
Я использую MimetypesFileTypeMap и добавьте любой mime, которого там нет, и мне это особенно нужно, в mime.типы файлов.
и теперь, долго читать:
прежде всего, список типов MIME-это огромный смотрите здесь: https://www.iana.org/assignments/media-types/media-types.xhtml
мне нравится использовать стандартные средства сначала предоставлено JDK, и если это не сработает, я пойду и поищу что-то еще.
определить тип файла из расширения файла
начиная с 1.6, Java имеет MimetypesFileTypeMap, как указано в одном из ответов выше, и это самый простой способ определить тип mime:
new MimetypesFileTypeMap().getContentType( fileName );в своей реализации ванили это не делает много (т. е. это работает .html, но это не так.формат PNG.) Это, однако, очень просто добавить любой тип контента вы может понадобиться:
- создать файл с именем ' mime.типы ' в папке META-INF в вашем проекте
- добавьте строку для каждого типа mime, который вам нужен, и реализация по умолчанию не обеспечивает (есть сотни типов mime, и список растет с течением времени).
Пример записи для png и js файлов будет:
image/png png PNG application/javascript jsмима.типы формат файла, смотрите более подробную информацию здесь: https://docs.oracle.com/javase/7/docs/api/javax/activation/MimetypesFileTypeMap.html
определить тип файла из содержимого файла
начиная с 1.7, Java имеет java.НИО.файл.спи.FileTypeDetector, который определяет стандартный API для определения типа файла в реализация определенным образом.
чтобы получить тип mime для файла, вы просто используете файлы и этого в код:
Files.probeContentType(Paths.get("either file name or full path goes here"));определение API предоставляет средства, которые поддерживают либо для определения типа mime файла из имени файла или из содержимого файла (magic bytes). Вот почему probeContentType() метод бросает IOException, в случае, если реализация этого API использует путь, предоставленный ему, чтобы фактически попытаться открыть файл, связанный с ним.
снова, ваниль реализация этого (тот, который поставляется с JDK) оставляет много, чтобы быть желанный.
в каком-то идеальном мире в далекой-далекой галактике все эти библиотеки, которые пытаются решить эту проблему типа файла в mime, просто реализуют java.НИО.файл.спи.FileTypeDetector, вы бы бросили в файл jar предпочтительной реализации библиотеки в свой путь к классам, и это было бы так.
в реальном мире, где вам нужен раздел TL, DR, вы должны найти библиотеку с большинством звезд рядом с ее именем и использовать ее. Для этого случай, мне он не нужен (пока ;)).
Это самый простой способ я нашел для этого:
byte[] byteArray = ... InputStream is = new BufferedInputStream(new ByteArrayInputStream(byteArray)); String mimeType = URLConnection.guessContentTypeFromStream(is);
Если вы работаете на ОС 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'
после попытки различных других библиотек я поселился с 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; }
вы можете сделать это только с одной строкой: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"))); } }этот код выдает следующие выходные данные: text / plain
Comments