java.nio.fichier.Chemin d'accès d'un chemin de classe de ressource
Est-il une API pour obtenir un chemin de classe de ressource (par exemple, ce que j'aimerais obtenir de de la Classe.getResource(String)
) comme un java.nio.file.Path
? Idéalement, je voudrais utiliser la fantaisie nouveau Chemin d'accès Api avec classpath ressources.
- Eh bien, prendre le long chemin (pun intended), vous avez
Paths.get(URI)
, puis l'URL.t(), and last
getResource () " qui retourne unURL
. Vous pourriez être en mesure de la chaîne d'ensemble. Havent essayé de bien.
Vous devez vous connecter pour publier un commentaire.
Celui-ci fonctionne pour moi:
Deviner que ce que vous voulez faire, c'est appeler les Fichiers.les lignes(...) sur une ressource qui vient de le classpath - peut-être dans un bocal.
Depuis Oracle alambiqué la notion de quand un Chemin est un Chemin en ne faisant pas de getResource retour utilisable chemin si elle réside dans un fichier jar, ce que vous devez faire est quelque chose comme ceci:
class.getResource
nécessite une barre oblique maisgetSystemResourceAsStream
ne trouve pas le fichier s'il est préfixé par un slash.La plus générale, la solution est la suivante:
L'obstacle principal est de traiter les deux possibilités, soit, avoir un système de fichier en cours que nous devrions utiliser, mais pas à proximité (comme avec
file
Uri ou le Java 9 du module de stockage), ou d'avoir à ouvrir et donc de fermer le système de fichiers nous-mêmes (zip/fichiers jar).Par conséquent, la solution ci-dessus encapsule l'action réelle dans un
interface
, gère les deux cas, la sécurité de fermeture par la suite dans le second cas, et des œuvres de Java 7 de Java 10. Il examine s'il existe déjà un système de fichiers ouverts avant d'en ouvrir un nouveau, de sorte qu'il fonctionne également dans le cas où un autre composant de votre application dispose déjà d'un système de fichiers pour le même zip/fichier jar.Il peut être utilisé dans toutes les versions de Java nommé ci-dessus, par exemple pour lister le contenu d'un paquet (
java.lang
dans l'exemple) quePath
s, comme ceci:Avec Java 8 ou plus récent, vous pouvez utiliser des expressions lambda ou de la méthode références de représenter le réel de l'action, par exemple
à faire de même.
La dernière version de Java 9 module du système a brisé le code ci-dessus par exemple. La JRE de façon incohérente retourne le chemin d'accès
/java.base/java/lang/Object.class
pourObject.class.getResource("Object.class")
alors qu'elle devrait être/modules/java.base/java/lang/Object.class
. Ceci peut être corrigé en ajoutant le manque/modules/
lorsque le chemin d'accès parent est signalé comme non-existant:Ensuite, il travaillera de nouveau avec toutes les versions et les méthodes de stockage.
Il s'avère que vous pouvez faire cela, avec l'aide de l'intégré dans Zip fournisseur de Système de Fichiers. Cependant, le passage d'une ressource URI directement à
Paths.get
ne fonctionnera pas; au lieu de cela, on doit d'abord créer un système de fichiers zip pour le pot d'URI, sans le nom de l'entrée, puis reportez-vous à l'entrée dans le système de fichiers:Mise à jour:
Il a été souligné à juste titre que le code ci-dessus contient une fuite de ressources, étant donné que le code s'ouvre un nouveau système de fichiers de l'objet, mais jamais le ferme. La meilleure approche est de faire passer un Consommateur comme un travailleur de l'objet, un peu comme la façon dont Holger la réponse t-il. Ouvrez le ZipFS système de fichiers, juste assez longtemps pour le travailleur de faire ce qu'il doit faire, avec le Chemin d'accès (aussi longtemps que le travailleur n'est pas d'essayer de stocker le Chemin de l'objet pour l'utiliser plus tard), puis fermez le système de fichiers.
newFileSystem
peut mener à de multiples ressources traîner ouvert à jamais. Bien que @raisercostin additif évite l'erreur en essayant de créer un déjà créé de système de fichiers, si vous essayez d'utiliser le retour de l'Path
vous obtiendrez unClosedFileSystemException
. @Holger réponse qui fonctionne bien pour moi.J'ai écrit une petite méthode d'aide à lire
Paths
à partir de votre classe de ressources. Il est assez pratique à utiliser car il ne nécessite qu'une seule référence de la classe, vous avez stocké vos ressources ainsi que le nom de la ressource elle-même.Vous ne pouvez pas créer des URI à partir de ressources à l'intérieur du fichier jar. Vous pouvez tout simplement l'écrire dans le fichier temp et ensuite l'utiliser (java8):
Lire un Fichier à partir du dossier de ressources à l'aide de NIO, dans java8
Vous avez besoin de définir le système de fichiers pour lire la ressource de fichier jar comme mentionné dans https://docs.oracle.com/javase/8/docs/technotes/guides/io/fsp/zipfilesystemprovider.html. J'succès pour lire la ressource de fichier jar avec ci-dessous les codes: