Comment récupérer le type MIME des fichiers ?
Contexte
Dans le cadre d’un projet, j’ai eu besoin de déterminer le type MIME des fichiers. Je suis parti à la recherche de solution pour résoudre ce point. J’ai trouvé la librairie Apache Tika mais des solutions existent dans le JDK.
Solution Apache Tika
La librairie Apache Tika est un outil pour analyser le contenu des fichiers (détection, extraction des métadonnées ou du contenu de texte structuré).
Pour cela, il suffit d’inclure la librairie suivante :
<dependency>
<groupId>org.apache.tika</groupId>
<artifactId>tika-core</artifactId>
<version>1.25</version>
</dependency>
Ensuite, le code est très simple car la librairie propose une classe Facade Tika
qui fournit un certain nombre de services dont celui qui nous intéresse.
import org.apache.tika.Tika;
String typeMime = new Tika().detect(new File("/emplacement/de/mon/fichier"));
System.out.println("Type Mime trouvé : " + typeMime);
Solution JDK
Depuis le JDK 7, il existe déjà une solution pour détecter le type MIME.
En effet, la classe Files
possède une méthode statique probeContentType
import java.nio.file.Files;
String typeMime = Files.probeContentType(Path.of("/emplacement/de/mon/fichier"));
System.out.println("Type Mime trouvé : " + typeMime);
Cela fonctionne très bien mais il possède malheureusement des limites.
L’implémentation existante se base sur la RFC 2045: Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies. La détection est réalisée sur le nom du fichier.
Cela implique que le contenu du fichier n’est pas exploité. L’effet de bord est que cela fonctionne même si le fichier n’existe pas.
C’est à dire que le même fichier (même contenu) va produire des résultats différents en fonction du nom de ce dernier.
- mon-fichier.xml => application/xml
- mon-fichier.xml.txt => text/plain
- mon-fichier => null
Amélioration de la solution JDK
Le JDK offre une classe abstraite java.nio.file.spi.FileTypeDetector
qui permet d’enrichir le système de détection par défaut.
Donc nous pouvons implémenter un détecteur utilisant la librairie Apache Tika.
public class TikaFileTypeDetector extends FileTypeDetector {
@Override
public String probeContentType(Path path) throws IOException {
return new Tika().detect(path);
}
}
Le principe d’extension utilise le mécanisme de ServiceLoader
afin que le JDK utilise notre classe. C’est à dire que nous allons créer un répertoire META-INF/services
et y placer le fichier s’appelant le nom de l’interface java.nio.file.spi.FileTypeDetector
contenant le nom de notre classe d’implémentation et le tour est joué.
Ainsi, notre code utilise seulement le JDK sans dépendance externe et nous bénéficions des avantages de détection de la librarie Apache Tika.
Solution existante
Le projet Apache Tika a prévu aussi cette mise en oeuvre et l’a fait pour nous. Pour l’utiliser, il suffit de choisir le module tika-java7.
<dependency>
<groupId>org.apache.tika</groupId>
<artifactId>tika-java7</artifactId>
<version>1.25</version>
</dependency>
En important le module tika-java7
, nous n’avons plus besoin d’importer le module tika-core
Le nom du module peut améner une confusion en suggérant que le module fonctionne uniquement avec un JDK 7.
Et bien non, la signification -java7
indique simplement que la librairie implémente la classe abstraite FileTypeDetector
ajoutée dans le JDK 7.
Compléments
Au niveau de la librairie Apache Tika, il est à noter une différence de traitement si nous passons en argument une instance de String
ou une instance de File
à la méhode detect
-
Si le paramètre est un
String
, cela implique une détection par le nom -
Si le paramètre est un
File
, cela implique une détection par le contenu
Bonne détection !
Moteur de recherche
"Eduquer, ce n'est pas remplir des vases mais c'est d'allumer des feux." - Michel Montaigne
Billets récents
- Eclipse plante systématiquement sous Debian (et autres distribution Linux)
- JEP 463, Implicitly Declared Classes and Instance Main Methods (Second Preview)
- Debian - Montée de version de Debian 11 (Bullseye) à Debian 12 (Bookworm)
- JEP 451, Prepare to Disallow the Dynamic Loading of Agents
- JEP 444, Virtual Threads