Question

Je me demandais simplement comment la plupart des gens récupèrent un type MIME à partir d'un fichier en Java ?Jusqu'à présent, j'ai essayé deux utilitaires : JMimeMagic & Mime-Util.

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

Était-ce utile?

La solution

Dans Java 7, vous pouvez désormais simplement utiliser Files.probeContentType(path).

Autres conseils

Malheureusement,

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

ne fonctionne pas, puisque cette utilisation de l'URL laisse un fichier verrouillé, de sorte que, par exemple, il ne puisse pas être supprimé.

Par contre tu as ceci :

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

et aussi le suivant, qui a l'avantage d'aller au-delà de la simple utilisation d'extension de fichier, et de jeter un œil au contenu

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

Cependant, comme le suggère le commentaire ci-dessus, le tableau intégré des types MIME est assez limité et n'inclut pas, par exemple, MSWord et PDF.Donc, si vous souhaitez généraliser, vous devrez aller au-delà des bibliothèques intégrées, en utilisant, par exemple, Mime-Util (qui est une excellente bibliothèque, utilisant à la fois l'extension et le contenu des fichiers).

L'API JAF fait partie du JDK 6.Regarder javax.activation emballer.

Les cours les plus intéressants sont javax.activation.MimeType - un véritable détenteur de type MIME - et javax.activation.MimetypesFileTypeMap - classe dont l'instance peut résoudre le type MIME en String 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);

Avec Apache Tika tu as seulement besoin 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 géniale, collez et exécutez simplement 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 analyser « n’importe quoi ».Depuis 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 les apidocs pour plus d'informations.

Apache Tika offres en tika-core une détection de type MIME basée sur des marqueurs magiques dans le préfixe du flux. tika-core ne récupère pas les autres dépendances, ce qui le rend aussi léger que le Utilitaire de détection de type MIME.

Exemple de code simple (Java 7), 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();
}

Veuillez noter que MediaType.detect(...) ne peut pas être utilisé directement (TIKA-1120).Plus d'indices sont fournis sur https://tika.apache.org/0.10/detection.html.

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

Depuis roseinde:

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

Si vous êtes bloqué avec Java 5-6 alors cette classe utilitaire de produit open source servoy.

Vous n'avez besoin que de cette fonction

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

Il sonde les premiers octets du contenu et renvoie les types de contenu en fonction de ce contenu et non par extension de fichier.

Je me demandais simplement comment la plupart des gens récupèrent un type MIME à partir d'un fichier en Java ?

J'ai publié mon SimpleMagie Package Java qui permet la détermination du type de contenu (type MIME) à partir de fichiers et de tableaux d'octets.Il est conçu pour lire et exécuter les fichiers magiques de commande Unix file(1) qui font partie de la plupart des configurations ~Unix OS.

J'ai essayé Apache Tika mais c'est le cas énorme avec des tonnes de dépendances, URLConnection n'utilise pas les octets des fichiers, et MimetypesFileTypeMap regarde également simplement 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();
}

Pour participer avec mes 5 centimes :

TL,DR

j'utilise Types MIMEFileTypeMap et ajoutez tout mime qui n'est pas là et dont j'ai spécifiquement besoin, dans le fichier mime.types.

Et maintenant, la longue lecture :

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

J'aime d'abord utiliser les fonctionnalités standard fournies par JDK, et si cela ne fonctionne pas, je chercherai autre chose.

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

Depuis la version 1.6, Java a MimetypesFileTypeMap, comme indiqué dans l'une des réponses ci-dessus, et c'est le moyen le plus simple de déterminer le type MIME :

new MimetypesFileTypeMap().getContentType( fileName );

Dans son implémentation vanille, cela ne fait pas grand-chose (c'est-à-direcela fonctionne pour .html mais pas pour .png).Il est cependant très simple d’ajouter n’importe quel type de contenu dont vous pourriez avoir besoin :

  1. Créez un fichier nommé 'mime.types' dans le dossier META-INF de votre projet
  2. Ajoutez une ligne pour chaque type MIME dont vous avez besoin et l'implémentation par défaut ne le fournit pas (il existe des centaines de types MIME et la liste s'allonge avec le temps).

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

image/png png PNG
application/javascript js

Pour le format de fichier mime.types, 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 la version 1.7, Java a java.nio.file.spi.FileTypeDetector, qui définit une API standard pour déterminer un type de fichier dans manière spécifique à la mise en œuvre.

Pour récupérer le type MIME d'un fichier, vous utiliserez simplement Des dossiers et fais ceci dans ton code :

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

La définition de l'API fournit des fonctionnalités permettant de déterminer le type MIME du fichier à partir du nom du fichier ou du contenu du fichier (octets magiques).C'est pourquoi sondeContentType() La méthode lève IOException, dans le cas où une implémentation de cette API utilise le chemin qui lui est fourni pour essayer d'ouvrir le fichier qui lui est associé.

Encore une fois, la vanille mise en œuvre de ceci (celui fourni avec JDK) laisse beaucoup à désirer.

Dans un monde idéal dans une galaxie lointaine, très lointaine, toutes ces bibliothèques qui tentent de résoudre ce problème de type fichier vers MIME implémenteraient simplement java.nio.file.spi.FileTypeDetector, vous déposeriez le fichier jar de la bibliothèque d'implémentation préférée dans votre chemin de classe et ce serait tout.

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

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

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

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

Vous pouvez d’abord vérifier le mimeType et le valider.

Deuxièmement, vous devriez chercher à convertir les 4 premiers octets de votre fichier en hexadécimal, puis le comparer avec les nombres magiques.Ce sera alors un moyen vraiment sécurisé de vérifier les validations de fichiers.

au printemps Fichier Multipart déposer;

org.springframework.web.multipart.MultipartFile

file.getContentType();

C'est le moyen le plus simple que j'ai trouvé pour procéder :

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

si vous travaillez sous Linux, il existe 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 "";
}

Alors

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

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

Après avoir essayé diverses autres bibliothèques, j'ai opté pour 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;
}

Vous pouvez le faire avec une seule ligne : MimetypesFileTypeMap().getContentType(new File("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 le résultat suivant : texte simple

File file = new File(PropertiesReader.FILE_PATH);
MimetypesFileTypeMap fileTypeMap = new MimetypesFileTypeMap();
String mimeType = fileTypeMap.getContentType(file);
URLConnection uconnection = file.toURL().openConnection();
mimeType = uconnection.getContentType();
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top