Je charge un fichier texte à partir d'un package dans un JAR compilé de mon projet Java. La structure de répertoire pertinente est la suivante:
/src/initialization/Lifepaths.txt
Mon code charge un fichier en appelant Class::getResourceAsStream
pour retourner un fichier InputStream
.
public class Lifepaths {
public static void execute() {
System.out.println(Lifepaths.class.getClass().
getResourceAsStream("/initialization/Lifepaths.txt"));
}
private Lifepaths() {}
//This is temporary; will eventually be called from outside
public static void main(String[] args) {execute();}
}
L'impression sera toujours imprimée null
, peu importe ce que j'utilise. Je ne sais pas pourquoi ce qui précède ne fonctionnerait pas, alors j'ai également essayé:
"/src/initialization/Lifepaths.txt"
"initialization/Lifepaths.txt"
"Lifepaths.txt"
Aucun de ces travaux. J'ai lu de nombreuses questions sur le sujet jusqu'à présent, mais aucune d'entre elles n'a été utile - généralement, ils disent simplement de charger les fichiers en utilisant le chemin racine, ce que je fais déjà. Cela, ou simplement charger le fichier à partir du répertoire actuel (juste charger filename
), que j'ai également essayé. Le fichier est en cours de compilation dans le JAR à l'emplacement approprié avec le nom approprié.
Comment résoudre ce problème?
Lifepaths.class
. Cela étant dit, pourquoigetClassLoader()
permet-il de fonctionner? (Aussi, n'hésitez pas à poster une réponse!)Lifepaths.getClass()
? Il n'y a pas de méthode statique de ce type définie dans Object ...getResource(String)
. BTW - J'ai toujours eu des problèmes pour faire fonctionner l'un ou l'autre dans unstatic
contexte. Le problème est fondamentalement que le chargeur de classe obtenu est celui destiné aux classes J2SE. Vous devez avoir accès au chargeur de classe de contexte qui est destiné à l'application elle-même.Réponses:
Lifepaths.class.getClass().getResourceAsStream(...)
charge les ressources à l'aide du chargeur de classe système, il échoue évidemment car il ne voit pas vos JARLifepaths.class.getResourceAsStream(...)
charge les ressources en utilisant le même chargeur de classe que celui qui a chargé la classe Lifepaths et il doit avoir accès aux ressources de vos JARla source
/
avant votre chemin si votre fichier se trouve dans un répertoire différent; par exempleinitialization/Lifepaths.txt
. Si le chemin du fichier est le même que celui de votre classe (mais sous ressources comme répertoire principal), vous pouvez simplement mettre le nom du fichier sans aucun/
. Par exemple, si votre classe a le chemin suivantsrc/main/java/paths/Lifepaths.java
, votre fichier doit avoir ce cheminsrc/main/resources/paths/Lifepaths.txt
.Les règles sont les suivantes:
Et essaye:
au lieu de
(je ne sais pas si cela fait une différence, mais le premier utilisera le bon ClassLoader / JAR, alors que je ne suis pas sûr du dernier)
la source
Il existe donc plusieurs façons d'obtenir une ressource à partir d'un fichier jar et chacune a une syntaxe légèrement différente où le chemin doit être spécifié différemment.
La meilleure explication que j'ai vue est cet article de JavaWorld . Je vais résumer ici, mais si vous voulez en savoir plus, vous devriez consulter l'article.
Méthodes
1)
ClassLoader.getResourceAsStream()
.Format: "/" - noms séparés; pas de "/" de tête (tous les noms sont absolus).
Exemple:
this.getClass().getClassLoader().getResourceAsStream("some/pkg/resource.properties");
2)
Class.getResourceAsStream()
Format: "/" - noms séparés; "/" en tête indique des noms absolus; tous les autres noms sont relatifs au package de la classe
Exemple:
this.getClass().getResourceAsStream("/some/pkg/resource.properties");
la source
N'utilisez pas de chemins absolus, rendez-les relatifs au répertoire 'resources' de votre projet. Code rapide et sale qui affiche le contenu de MyTest.txt à partir du répertoire 'resources'.
la source
Vous voudrez peut-être essayer ceci pour obtenir le flux, c'est-à-dire obtenir d'abord l'url puis l'ouvrir en tant que flux.
Une fois, j'ai eu une question similaire: la lecture du fichier txt à partir du jar échoue mais la lecture de l'image fonctionne
la source
Il semble y avoir un problème avec le ClassLoader que vous utilisez. Utilisez le contextClassLoader pour charger la classe. Ceci indépendamment du fait que ce soit dans une méthode statique / non statique
Thread.currentThread().getContextClassLoader().getResourceAsStream
......la source
Je me suis retrouvé dans un problème similaire. Depuis que j'utilise maven, j'ai dû mettre à jour mon pom.xml pour inclure quelque chose comme ceci:
Notez la balise de ressource pour spécifier où se trouve ce dossier. Si vous avez des projets imbriqués (comme moi), vous voudrez peut-être obtenir des ressources d'autres domaines plutôt que simplement dans le module dans lequel vous travaillez. Cela permet de réduire la conservation du même fichier dans chaque dépôt si vous utilisez des données de configuration similaires
la source
Ce qui a fonctionné pour moi, c'est d'ajouter le fichier sous
My Project/Java Resources/src
puis d'utiliserJe n'avais pas besoin d'ajouter explicitement ce fichier au chemin (l'ajouter à le
/src
fait apparemment)la source
Je ne sais pas si cela est utile, mais dans mon cas, j'avais ma ressource dans le dossier / src / et j'obtenais cette erreur. J'ai ensuite déplacé l'image dans le dossier bin et cela a résolu le problème.
la source
Assurez-vous que votre répertoire de ressources (par exemple "src") est dans votre chemin de classe (assurez-vous qu'il s'agit d'un répertoire source dans votre chemin de construction dans eclipse).
Assurez-vous que clazz est chargé depuis le chargeur de classe principal.
Ensuite, pour charger src / initialization / Lifepaths.txt, utilisez
Pourquoi:
clazz.getResourcesAsStream(foo)
recherche foo dans le classpath de clazz , par rapport au répertoire dans lequel clazz vit . Le premier "/" le charge à partir de la racine de n'importe quel répertoire dans le classpath de clazz.À moins que vous ne soyez dans un conteneur d'un type quelconque, comme Tomcat, ou que vous fassiez quelque chose directement avec ClassLoaders, vous pouvez simplement traiter votre chemin de classe eclipse / ligne de commande comme le seul chemin de classe du chargeur de classe.
la source
Le chargeur de classe JVM par défaut utilisera le chargeur de classe parent pour charger les ressources en premier: .
Lifepaths.class.getClass()
Le chargeur de classe estbootstrap classloader
, doncgetResourceAsStream
recherchera uniquement $ JAVA_HOME, quel que soit l'utilisateur fourniclasspath
. De toute évidence, Lifepaths.txt n'est pas là.Lifepaths.class
Le classloader de estsystem classpath classloader
, de mêmegetResourceAsStream
que la recherche définie par l'utilisateurclasspath
et Lifepaths.txt est là.Lors de l'utilisation
java.lang.Class#getResourceAsStream(String name)
, le nom qui ne commence pas par '/' sera ajouté avecpackage name
comme préfixe. Si vous voulez éviter cela, veuillez utiliserjava.lang.ClassLoader#getResourceAsStream
. Par exemple:la source
Grosso modo:
getClass().getResource("/")
~ =Thread.currentThread().getContextClassLoader().getResource(".")
Supposons que la structure de votre projet soit la suivante:
la source
si vous utilisez Maven, assurez-vous que votre emballage est «pot» et non «pom».
la source
Ce dont vous avez vraiment besoin est un chemin de classe absolu complet pour le fichier. Donc, au lieu de le deviner, essayez de trouver le ROOT, puis déplacez le fichier vers un meilleur emplacement base une structure de fichier <.war> ...
la source
Ce qui a fonctionné pour moi, c'est que j'ai placé le fichier sous
et
la source
src/main/JAVA
, évidemment vos fichiers non codés ne doivent pas se trouver ici.@Emracool ... Je vous suggère une alternative. Puisque vous semblez essayer de charger un fichier * .txt. Mieux vaut utiliser
FileInputStream()
plutôt que cegetClass().getClassLoader().getResourceAsStream()
ou ennuyeuxgetClass().getResourceAsStream()
. Au moins, votre code s'exécutera correctement.la source