Obtenir le type Mime D'un fichier en Java

je me demandais juste comment la plupart des gens récupèrent un type mime d'un fichier en Java? Jusqu'à présent, j'ai essayé deux utils: JMimeMagic et Mime-Util .

le premier m'a donné des exceptions de mémoire, le second ne ferme pas ses flux correctement. Je me demandais juste si quelqu'un d'autre avait une méthode/bibliothèque qu'il utilisait et fonctionnait correctement?

298
demandé sur NoobEditor 2008-09-09 13:11:06

18 réponses

en Java 7, vous pouvez maintenant utiliser Files.probeContentType(path) .

294
répondu Chris Mowforth 2013-07-26 23:49:52

malheureusement,

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

ne fonctionne pas, puisque cette utilisation d'URL laisse un fichier verrouillé, de sorte que, par exemple, il est indélébile.

cependant, vous avez ceci:

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

et aussi ce qui suit, qui a l'avantage d'aller au-delà de la simple utilisation de l'extension de fichier, et jette un oeil au contenu

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

Toutefois, comme le suggère le commentaire ci-dessus, le tableau de mime-types est assez limité, ne comprenant pas, par exemple, MSWord et PDF. Donc, si vous voulez généraliser, vous aurez besoin d'aller au-delà des bibliothèques intégrées, en utilisant, par exemple, Mime-Util (qui est une grande bibliothèque, en utilisant à la fois l'extension du fichier et le contenu).

191
répondu Joshua Fox 2010-06-06 15:36:41

L'API JAF fait partie de JDK 6. Regardez le paquet javax.activation .

les classes les plus intéressantes sont javax.activation.MimeType - un support de type MIME réel - et javax.activation.MimetypesFileTypeMap - classe dont l'instance peut résoudre le type MIME comme chaîne de caractères pour un fichier:

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);
47
répondu Adam Hošek 2009-12-14 17:02:50

Avec Apache Tika vous avez seulement besoin de trois lignes de code :

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

si vous avez une console groovy, il suffit de coller et d'exécuter ce code pour jouer avec:

@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)

gardez à l'esprit que ses API sont riches, il peut Parser "n'importe quoi". À partir de tika-core 1.14, vous avez:

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)

Voir la apidocs pour plus d'informations.

30
répondu lifeisfoo 2017-10-16 10:42:47

Apache Tika offre dans tika-core une détection de type mime basée sur des marqueurs magiques dans le préfixe stream. tika-core ne récupère pas d'autres dépendances, ce qui le rend aussi léger que l'utilitaire de détection de type Mime actuellement non maintenu .

exemple de code Simple (Java 7), en utilisant les variables theInputStream et 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();
}

S'il vous plaît notez que MediaType.détecter.(..) ne peut pas être utilisé directement ( TIKA-1120 ). Plus de conseils sont fournis à https://tika.apache.org/0.10/detection.html .

22
répondu koppor 2015-03-01 01:35:24

si vous êtes un développeur Android, vous pouvez utiliser une classe utilitaire android.webkit.MimeTypeMap qui mappe les types MIME aux extensions de fichiers et vice versa.

l'extrait de code suivant peut vous aider.

private static String getMimeType(String fileUrl) {
    String extension = MimeTypeMap.getFileExtensionFromUrl(fileUrl);
    return MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
}
19
répondu Pawan 2012-12-15 06:23:39

à Partir de roseindia :

FileNameMap fileNameMap = URLConnection.getFileNameMap();
String mimeType = fileNameMap.getContentTypeFor("alert.gif");
17
répondu AlikElzin-kilaka 2011-08-01 13:34:59

si vous êtes bloqué avec java 5-6 alors cette classe d'utilitaire de servoy open source produit

https://github.com/Servoy/servoy-client/blob/e7f5bce3c3dc0f0eb1cd240fce48c75143a25432/servoy_shared/src/com/servoy/j2db/util/MimeTypes.java#L34

vous n'avez besoin de cette fonction que

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

Il sonde les premiers octets du contenu et retourne les types de contenu basé sur ce contenu et non par extension de fichier.

13
répondu Ovidiu Buligan 2014-08-27 06:49:40

je me demandais juste comment la plupart des gens récupèrent un type mime d'un fichier en Java?

j'ai publié mon paquet Java SimpleMagic qui permet la détermination du type de contenu (mime-type) à partir des fichiers et des tableaux d'octets. Il est conçu pour lire et exécuter les fichiers magic de la commande Unix(1) qui font partie de la plupart des configurations ~Unix OS.

J'ai essayé Apache Tika mais c'est énorme avec des tonnes de dépendances, URLConnection n'utilise pas les octets des fichiers, et MimetypesFileTypeMap regarde aussi juste les noms de fichiers.

avec SimpleMagic vous pouvez faire quelque chose comme:

// 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();
}
11
répondu Gray 2017-05-30 21:38:01

j'ai essayé plusieurs façons de le faire, y compris les premières dites par @Joshua Fox. Mais certains ne reconnaissent pas les mimétypes fréquents comme pour les fichiers PDF, et d'autres ne pouvaient pas être fiables avec les faux fichiers (j'ai essayé avec un fichier RAR avec extension changée en TIF). La solution que j'ai trouvée, comme le dit aussi @Joshua Fox de manière superficielle, est d'utiliser MimeUtil2 , comme ceci:

MimeUtil2 mimeUtil = new MimeUtil2();
mimeUtil.registerMimeDetector("eu.medsea.mimeutil.detector.MagicMimeMimeDetector");
String mimeType = MimeUtil2.getMostSpecificMimeType(mimeUtil.getMimeTypes(file)).toString();
3
répondu ricardoc 2017-02-14 23:56:11

Il est préférable d'utiliser deux couches de validation de téléchargement de fichiers.

tout d'abord, vous pouvez vérifier pour le mimeType et de le valider.

ensuite, vous devriez chercher à convertir les 4 premiers octets de votre fichier en hexadécimal et ensuite comparer avec les nombres magiques. Alors il sera vraiment sûr moyen de vérifier la validation de fichier.

2
répondu javacreed 2014-08-19 09:26:03

à la carte À puce avec mon 5 cents:

TL, DR

j'utilise MimetypesFileTypeMap et d'ajouter tout de mime qui n'est pas là et j'ai précisément besoin, en mime.types de fichiers.

et maintenant, le long lire:

tout d'abord, la liste des types MIME est énorme , voir ici: https://www.iana.org/assignments/media-types/media-types.xhtml

j'aime utiliser les installations standard fournies par JDK d'abord, et si cela ne fonctionne pas, je vais aller chercher autre chose.

déterminer le type de fichier à partir de l'extension de fichier

depuis 1.6, Java a MimetypesFileTypeMap, comme indiqué dans l'une des réponses ci-dessus, et c'est la façon la plus simple de déterminer le type mime:

new MimetypesFileTypeMap().getContentType( fileName );

dans son implémentation vanille cela ne fait pas beaucoup (i.e. il fonctionne pour .html mais ce n'est pas pour .png). Il est cependant très simple d'ajouter n'importe quel type de contenu dont vous avez besoin:

  1. créer un fichier nommé 'mime.types 'dans le dossier META-INF de votre projet
  2. ajouter une ligne pour chaque type mime dont vous avez besoin et l'implémentation par défaut ne fournit pas (il y a des centaines de types mime et la liste croît avec le temps).

exemples d'entrées pour les fichiers png et js:

image/png png PNG
application/javascript js

pour mime.types format de fichier, Voir plus de détails ici: https://docs.oracle.com/javase/7/docs/api/javax/activation/MimetypesFileTypeMap.html

déterminer le type de fichier à partir du contenu du fichier

depuis 1.7, Java a java.nio.fichier.le spi.FileTypeDetector , qui définit un API standard pour déterminer un type de fichier dans implementation specific way .

pour obtenir le type mime d'un fichier, il vous suffit d'utiliser Files et de le faire dans votre code:

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

la définition de L'API prévoit des fonctionnalités qui prennent en charge soit la détermination du type mime du fichier à partir du nom du fichier, soit à partir du contenu du fichier (octets magiques). C'est pourquoi la méthode probeContentType() lance IOException, dans le cas où une implémentation de cette API utilise le chemin qui lui est fourni pour réellement essayer d'ouvrir le fichier qui lui est associé.

encore une fois, vanille mise en œuvre de ce (celui qui vient avec JDK) laisse beaucoup à désirer.

dans un monde idéal dans une galaxie très, très lointaine, toutes ces bibliothèques qui tentent de résoudre ce problème de type fichier-à-mime ne feraient qu'implémenter Java.nio.fichier.le spi.FileTypeDetector , vous déposeriez le fichier jar de la bibliothèque d'implémentation préférée dans votre classpath et ce serait tout.

dans le monde réel, celui où vous avez besoin de TL,section DR, vous devriez trouver la bibliothèque avec la plupart des étoiles à côté de son nom et de l'utiliser. Pour ce cas particulier, je n'en ai pas besoin (encore ;) ).

2
répondu nidalpres 2017-09-25 14:03:28

C'est le moyen le plus simple que j'ai trouvé pour faire ceci:

byte[] byteArray = ...
InputStream is = new BufferedInputStream(new ByteArrayInputStream(byteArray));
String mimeType = URLConnection.guessContentTypeFromStream(is);
1
répondu madx 2017-02-23 14:16:41

si vous travaillez sur linux OS ,il y a une ligne de commande 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 "";
}

puis

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

mimetype("/var/www/ggg/au.mp3") //  'audio/mp3'
0
répondu Abdennour TOUMI 2016-01-24 10:32:01

au printemps MultipartFile "151930920 de fichier";

org.springframework.Web.multipart.MultipartFile

file.getContentType();

0
répondu AhmadReza 2016-04-26 11:33:13

après avoir essayé diverses autres bibliothèques, je me suis installé avec 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);
0
répondu K. Siva Prasad Reddy 2016-05-26 12:35:24
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;
}
0
répondu Vazgen Torosyan 2016-11-23 13:26:18

vous pouvez le faire avec une seule ligne: MimetypesFileTypeMap().getContentType (nouveau fichier " filename.ext")) . Regardez le code de test complet (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")));
    }
}

ce code produit la sortie suivante: text / plain

-1
répondu Cassio Seffrin 2018-04-21 02:28:14