Je me demande quelle est la différence entre Class.getResource()
et ClassLoader.getResource()
?
edit: Je veux surtout savoir si une mise en cache est impliquée au niveau du fichier / répertoire. Comme dans "les listes de répertoires sont-elles mises en cache dans la version de classe?"
L'AFAIK devrait essentiellement faire de même, mais ce n'est pas le cas:
getClass().getResource()
getClass().getClassLoader().getResource()
J'ai découvert cela en jouant avec du code de génération de rapport qui crée un nouveau fichier à WEB-INF/classes/
partir d'un fichier existant dans ce répertoire. Lorsque j'utilisais la méthode de Class, je pouvais trouver des fichiers qui étaient là lors du déploiement en utilisant getClass().getResource()
, mais en essayant de récupérer le fichier nouvellement créé, j'ai reçu un objet nul. La navigation dans le répertoire montre clairement que le nouveau fichier est là. Les noms de fichiers ont été précédés d'une barre oblique comme dans "/myFile.txt".
La ClassLoader
version de getResource()
d'autre part a trouvé le fichier généré. D'après cette expérience, il semble qu'il y ait une sorte de mise en cache de la liste des répertoires en cours. Ai-je raison, et si oui, où est-ce documenté?
Depuis les documents de l' API surClass.getResource()
Recherche une ressource avec un nom donné. Les règles de recherche des ressources associées à une classe donnée sont implémentées par le chargeur de classe définissant la classe. Cette méthode délègue au chargeur de classe de cet objet. Si cet objet a été chargé par le chargeur de classe d'amorçage, la méthode délègue à ClassLoader.getSystemResource (java.lang.String).
Pour moi, cela se lit "Class.getResource appelle vraiment son propre chargeur de classe getResource ()". Ce qui reviendrait à le faire getClass().getClassLoader().getResource()
. Mais ce n'est évidemment pas le cas. Quelqu'un pourrait-il me fournir un éclairage sur cette question?
la source
Class.getResource
peut prendre un nom de ressource "relatif", qui est traité par rapport au package de la classe. Vous pouvez également spécifier un nom de ressource "absolu" à l'aide d'une barre oblique. Les chemins d'accès aux ressources du chargeur de classe sont toujours considérés comme absolus.Les éléments suivants sont donc essentiellement équivalents:
Et il en va de même (mais ils sont différents des précédents):
la source
this.getClass().getClassLoader().getResource("/");
retourner null? Il ne devrait pas être le même quethis.getClass().getClassLoader().getResource(".");
Le premier appel recherche par rapport au
.class
fichier tandis que le dernier recherche par rapport à la racine du chemin de classe.Pour déboguer des problèmes comme ça, j'imprime l'URL:
la source
getClassLoader().getResource("/...")
renvoie toujoursnull
- le chargeur de classe ne supprime pas le début/
du chemin, donc la recherche échoue toujours.getClass().getResource()
Gère uniquement un début/
comme chemin absolu par rapport au chemin de classe.J'ai dû chercher dans les spécifications:
Class.getResource (ressource de chaîne)
ClassLoader.getResource (ressource de chaîne)
La documentation getResource () de la classe fait la différence:
la source
Toutes ces réponses ici, ainsi que les réponses à cette question , suggèrent que le chargement d'URL absolues, comme "/foo/bar.properties", est traité de la même manière par
class.getResourceAsStream(String)
etclass.getClassLoader().getResourceAsStream(String)
. Ce n'est PAS le cas, du moins pas dans ma configuration / version Tomcat (actuellement 7.0.40).Désolé, je n'ai absolument aucune explication satisfaisante, mais je suppose que Tomcat fait des tours sales et sa magie noire avec les chargeurs de classe et cause la différence. J'ai toujours utilisé
class.getResourceAsStream(String)
dans le passé et je n'ai eu aucun problème.PS: j'ai aussi posté ça ici
la source
Class.getResources
récupérerait la ressource par le chargeur de classe qui charge l'objet. WhileClassLoader.getResource
récupérerait la ressource à l'aide du chargeur de classe spécifié.la source
J'ai essayé de lire depuis input1.txt qui se trouvait dans l'un de mes packages avec la classe qui essayait de le lire.
Les oeuvres suivantes:
La partie la plus importante était d'appeler
getPath()
si vous voulez le nom de chemin correct au format String. NE PAS UTILISERtoString()
car il ajoutera du texte de mise en forme supplémentaire qui MESSERA TOTALEMENT le nom de fichier (vous pouvez l'essayer et voir l'impression).J'ai passé 2 heures à déboguer ceci ... :(
la source
FileReader
ouFileInputStream
ne peuvent pas être utilisés pour accéder eux. La réponse n'est pas correcte.