J’essayais de charger un fichier dans une application Web et je FileNotFound
une exception FileNotFound
lorsque j’utilisais FileInputStream
. Cependant, en utilisant le même chemin, j’ai pu charger le fichier lorsque j’ai getResourceAsStream()
. Quelle est la différence entre les deux méthodes et pourquoi l’une fonctionne-t-elle alors que l’autre ne fonctionne pas?
Le fichier java.io.File
and consorts agit sur le système de fichiers du disque local. La cause première de votre problème est que les chemins relatifs dans java.io
dépendent du répertoire de travail en cours. C’est-à-dire le répertoire à partir duquel la JVM (dans votre cas: celle du serveur Web) est démarrée. Cela peut être par exemple C:\Tomcat\bin
ou quelque chose de complètement différent, mais donc pas C:\Tomcat\webapps\contextname
ou quoi que ce soit. Dans un projet Eclipse normal, ce serait C:\Eclipse\workspace\projectname
. Vous pouvez en apprendre davantage sur le répertoire de travail actuel de la façon suivante:
System.out.println(new File(".").getAbsolutePath());
Cependant, le répertoire de travail n’est en aucun cas contrôlable par programmation. Vous devriez vraiment préférer utiliser des chemins absolus dans l’API de File
plutôt que des chemins relatifs. Par exemple, C:\full\path\to\file.ext
.
Vous ne voulez pas coder en dur ou deviner le chemin absolu dans les applications Java (Web). C’est seulement un problème de portabilité (c’est-à-dire qu’il fonctionne dans le système X, mais pas dans le système Y). La pratique normale consiste à placer ce type de ressources dans le classpath , ou à append son chemin d’access complet au classpath (dans un IDE comme Eclipse, il s’agit du dossier src
et du “build path”, respectivement). De cette façon, vous pouvez les récupérer avec l’aide de ClassLoader
par ClassLoader#getResource()
ou ClassLoader#getResourceAsStream()
. Il est capable de localiser les fichiers relatifs à la “racine” du classpath, comme vous l’avez compris par hasard. Dans les applications Web (ou toute autre application qui utilise plusieurs chargeurs de classes), il est recommandé d’utiliser ClassLoader
tel que retourné par Thread.currentThread().getContextClassLoader()
pour que vous puissiez également regarder “hors” du contexte de l’application Web.
Une autre alternative dans webapps est le ServletContext#getResource()
et son homologue ServletContext#getResourceAsStream()
. Il est possible d’accéder aux fichiers situés dans le dossier web
public du projet webapp, y compris le dossier /WEB-INF
. Le ServletContext
est disponible dans les servlets par la méthode getServletContext()
héritée, vous pouvez l’appeler tel quel.
getResourceAsStream
est le bon moyen de le faire pour les applications Web (comme vous l’avez déjà appris).
La raison en est que la lecture du système de fichiers ne peut pas fonctionner si vous empaquetez votre application Web dans un WAR. C’est la bonne façon de conditionner une application Web. C’est portable de cette façon, car vous ne dépendez pas d’un chemin de fichier absolu ou de l’emplacement d’installation de votre serveur d’applications.
FileInputStream charge le chemin de fichier que vous transmettez au constructeur en tant que relatif à partir du répertoire de travail du processus Java. Habituellement, dans un conteneur Web, cela ressemble au dossier bin
.
getResourceAsStream()
chargera un chemin de fichier par rapport au chemin de getResourceAsStream()
de votre application .
La classe FileInputStream
fonctionne directement avec le système de fichiers sous-jacent. Si le fichier en question n’est pas physiquement présent, il ne pourra pas l’ouvrir. La méthode getResourceAsStream()
fonctionne différemment. Il essaie de localiser et de charger la ressource à l’aide du ClassLoader
de la classe sur laquelle il est appelé. Cela lui permet de trouver, par exemple, des ressources incorporées dans des fichiers jar
.
classname.getResourceAsStream () charge un fichier via le classloader de classname. Si la classe provient d’un fichier JAR, c’est à partir de là que la ressource sera chargée.
FileInputStream est utilisé pour lire un fichier à partir du système de fichiers.