Question

J'essayais de charger un fichier dans une application Web et j'obtenais un FileNotFound exception quand j'ai utilisé FileInputStream.Cependant, en utilisant le même chemin, j'ai pu charger le fichier lorsque je l'ai fait 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 ?

Était-ce utile?

La solution

Le java.io.File agit sur et consorts le système de fichiers de disque local. La cause racine de votre problème est que relative chemins dans java.io dépendent du répertoire de travail courant. C'est à dire. le répertoire à partir duquel la machine virtuelle Java (dans votre cas: celui de serveur web) est démarré. Cela peut par exemple être C:\Tomcat\bin ou tout autre chose, mais donc pas C:\Tomcat\webapps\contextname ou tout ce que vous vous attendez 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 en cours de la manière suivante:

System.out.println(new File(".").getAbsolutePath());

Cependant, le répertoire de travail est en aucun cas contrôlables par programmation. Vous devriez vraiment préférer utiliser absolu chemins dans l'API File au lieu de chemins relatifs. Par exemple. C:\full\path\to\file.ext.

Vous ne voulez pas deviner ou coder en dur le chemin absolu dans les applications Java (Web). C'est que la portabilité des problèmes (à savoir qu'il fonctionne dans le système X, mais pas dans le système Y). La pratique normale est de placer ce genre de ressources dans le classpath , ou d'ajouter son chemin complet du chemin de classe (dans un IDE comme Eclipse est le dossier src et le « chemin de génération », respectivement). De cette façon, vous pouvez les attraper avec l'aide du ClassLoader par ClassLoader#getResource() ou ClassLoader#getResourceAsStream() . Il est capable de localiser les fichiers par rapport à la « racine » du classpath, comme vous par hasard compris. En webapplications (ou toute autre application qui utilise plusieurs classloaders), il est recommandé d'utiliser le ClassLoader retourné par Thread.currentThread().getContextClassLoader() pour ce que vous pouvez regarder « en dehors » le contexte webapp ainsi.

Une autre alternative est le webapps ServletContext#getResource() et son homologue ServletContext#getResourceAsStream() . Il est capable d'accéder à des fichiers situés dans le dossier web public du projet webapp, y compris le dossier /WEB-INF. Le ServletContext est disponible en servlets par le getServletContext() méthode, vous pouvez l'appeler.

Voir aussi:

Autres conseils

getResourceAsStream est la bonne façon de le faire pour des applications Web (comme vous avez déjà appris).

La raison en est que la lecture du système de fichiers ne peut pas fonctionner si vous emballez votre application Web dans une guerre. Ceci est la bonne façon d'emballer une application web. Il est portable de cette façon, parce que vous n'êtes pas dépendant d'un chemin de fichier absolu ou l'emplacement où votre serveur d'applications est installé.

FileInputStream chargera un chemin de fichier que vous passez au constructeur par rapport de la répertoire de travail du processus Java. Habituellement, dans un conteneur Web, c'est quelque chose comme le dossier bin.

getResourceAsStream() chargera un chemin de fichier relatif à partir de votre application de classpath.

La classe FileInputStream travaille directement avec le système de fichiers sous-jacent. Si le fichier en question n'est pas physiquement présent là, il ne parviendra pas à l'ouvrir. La méthode de getResourceAsStream() fonctionne différemment. Il essaie de localiser et charger la ressource en utilisant la ClassLoader de la classe, 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 chargeur de classe de nom de classe. Si la classe est venu d'un fichier jar, qui est où la ressource sera chargé.

FileInputStream est utilisé pour lire un fichier à partir du système de fichiers.

Je suis ici en séparant les deux utilisations en les marquant comme File Read(java.io) et Resource Read(ClassLoader.getResourceAsStream()).

Lecture de fichier - 1.Fonctionne sur le système de fichiers local.2.Essaie de localiser le fichier demandé à partir du répertoire courant lancé par la JVM en tant que root 3.Idéalement idéal lorsque vous utilisez des fichiers pour le traitement dans un emplacement prédéterminé comme /dev/files ou C:\Data.

Lecture de la ressource -1.Travaux sur le parcours de classe 2.Essaie de localiser le fichier/la ressource dans le chemin de classe du chargeur de classe actuel ou parent.3.Idéalement, lorsque vous essayez de charger des fichiers à partir de fichiers packagés comme war ou jar.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top