La lecture d'un fichier de ressources à partir de l'intérieur de jar
Je voudrais lire une ressource à partir de l'intérieur de mon pot comme suit:
File file;
file = new File(getClass().getResource("/file.txt").toURI());
BufferredReader reader = new BufferedReader(new FileReader(file));
//Read the file
et il fonctionne très bien lors de l'exécution dans Eclipse, mais si je l'exporter dans un bocal de la course il y est une IllegalArgumentException:
Exception in thread "Thread-2"
java.lang.IllegalArgumentException: URI is not hierarchical
et je ne sais pas vraiment pourquoi, mais avec quelques essais j'ai trouvé si je change
file = new File(getClass().getResource("/file.txt").toURI());
à
file = new File(getClass().getResource("/folder/file.txt").toURI());
alors il fonctionne à l'inverse (il travaille dans le bocal mais pas de l'éclipse).
Je suis en utilisant Eclipse et le dossier avec mon fichier est dans un dossier de classe.
- Si vous voulez lire des fichiers d'un répertoire dans le bocal avec les numéros de fichiers, voir Stackoverflow-Link
- Je ne suis pas sûr que la question initiale a été impliquant Printemps. Le lien dans le commentaire précédent fait référence à un Ressort de réponse spécifique à partir d'une question différente. Je crois
getResourceAsStream
est encore plus simple et plus portable solution au problème.
InformationsquelleAutor PrinceCJC | 2013-12-05
Vous devez vous connecter pour publier un commentaire.
Plutôt que d'essayer de l'adresse de la ressource en tant que Fichier il suffit de demander le Chargeur de classe de retour d'un InputStream de la ressource par le biais d' getResourceAsStream:
Tant que le
file.txt
ressource est disponible dans le classpath ensuite, cette approche va fonctionner de la même façon, indépendamment de savoir si lefile.txt
ressource enclasses/
répertoire ou à l'intérieur d'unjar
.La
URI is not hierarchical
se produit parce que l'URI d'une ressource dans un fichier jar va ressembler à quelque chose comme ceci:file:/example.jar!/file.txt
. Vous ne pouvez pas lire les écritures dans unjar
(unzip
fichier) comme si c'était un simple vieux Fichier.C'est bien expliqué par les réponses à:
InputStream
existe (commeFile.exists()
) donc mon jeu pouvez indiquer si vous souhaitez utiliser le fichier par défaut ou non. Merci.getClass().getResource("**/folder**/file.txt")
fait le travail est parce que j'ai eu ce dossier dans le même répertoire que mon pot :).getResourceAsStream
retourne null si la ressource n'existe pas, de sorte que peut être votre "existe" de test.the URI for a resource within a jar file is going to look something like this: file:/example.jar!/file.txt
merci pour cette information, ce point d'exclamation dans l'URI a été déroutant pour moi.InputStream inputStream = this.getClass().getResourceAsStream(YourfilePath)
Pour accéder à un fichier dans un bocal, vous avez deux options:
Placez le fichier dans le répertoire de la structure correspondant à votre nom de paquet (après l'extraction .fichier jar, il devrait être dans le même répertoire que .fichier de classe), puis accéder à l'aide de
getClass().getResourceAsStream("file.txt")
Placer le fichier à la racine (après l'extraction .fichier jar, il doit être à la racine), puis accéder à l'aide de
Thread.currentThread().getContextClassLoader().getResourceAsStream("file.txt")
La première option peut ne pas fonctionner lorsque le pot est utilisé comme un plugin.
Si vous voulez lire un fichier, je crois qu'il y a toujours une solution similaire:
file:
URL.J'ai eu ce problème avant et j'ai fait de secours façon pour le chargement. Fondamentalement première façon de travailler de l'intérieur .fichier jar et le second moyen de travaux au sein d'eclipse ou autre IDE.
Assurez-vous que vous travaillez avec le bon séparateur. J'ai remplacé tous les
/
dans un chemin relatif avec unFile.separator
. Cela a bien fonctionné dans l'IDE, mais ne fonctionne pas dans la version JAR.Jusqu'à maintenant (décembre 2017), c'est la seule solution que j'ai trouvé qui fonctionne les deux à l'intérieur et à l'extérieur de l'IDE.
Utilisation PathMatchingResourcePatternResolver
Remarque: il travaille également au printemps-boot
Dans cet exemple, je suis en train de lire certains fichiers situés dans src/main/resources/mon_dossier:
Après beaucoup de creuser autour de Java, la seule solution qui semble fonctionner pour moi, c'est manuellement lire le fichier jar de lui-même, sauf si vous êtes dans un environnement de développement(IDE):
Remarque: Le code ci-dessus ne semble fonctionner correctement pour les fichiers jar si elle est dans la classe principale. Je ne sais pas pourquoi.
Je pense que cela devrait être fonctionne en java ainsi. Le code suivant que j'utilise est à l'aide de kotlin.
Pour quelque raison
classLoader.getResource()
retourne toujours la valeur null lorsque j'ai déployé l'application web de WildFly 14. l'obtention du chargeur de classe degetClass().getClassLoader()
ouThread.currentThread().getContextClassLoader()
renvoie la valeur null.getClass().getClassLoader()
API doc a dit,"Renvoie le chargeur de classe pour la classe. Certaines implémentations peuvent utiliser la valeur null pour représenter la classe de bootstrap loader. Cette méthode retourne la valeur null dans leur mise en œuvre si cette classe a été chargé par la classe de bootstrap loader."
peut-être si vous êtes à l'aide de WildFly et le vôtre application web essayez cette
request.getServletContext().getResource()
renvoyé l'url de ressource. Ici, la demande est un objet de ServletRequest.Le problème est que certaines bibliothèques tierces nécessitent des chemins d'accès des fichiers plutôt que de les flux d'entrée. La plupart des réponses ne répondent pas à cette question.
Dans ce cas, une solution consiste à copier le contenu d'une ressource dans un fichier temporaire. L'exemple suivant utilise jUnit est
TemporaryFolder
.Code ci-dessous fonctionne avec Spring boot(kotlin):
Vous pouvez utiliser le chargeur de classe qui sera lu à partir de classpath du chemin de la RACINE (sans le "/" au début)
Si vous utilisez le printemps, vous pouvez utiliser la méthode suivante pour lire le fichier de répertoire src/main/resources: