Comment lister les fichiers d'un fichier JAR?
J'ai ce code qui lit tous les fichiers d'un répertoire.
File textFolder = new File("text_directory");
File [] texFiles = textFolder.listFiles( new FileFilter() {
public boolean accept( File file ) {
return file.getName().endsWith(".txt");
}
});
Il fonctionne très bien. Il remplit le tableau avec tous les fichiers qui se terminent par ".txt" du répertoire "text_directory".
Comment puis-je lire le contenu d'un répertoire dans un mode similaire dans un fichier JAR?
Donc ce que je veux vraiment faire est de, à la liste de toutes les images à l'intérieur de mon fichier JAR, afin que je puisse les charger avec:
ImageIO.read(this.getClass().getResource("CompanyLogo.png"));
(Que l'on travaille parce que le "CompanyLogo" est "codé en dur", mais le nombre d'images à l'intérieur du fichier JAR peut être de 10 à 200 de longueur variable.)
MODIFIER
Donc je suppose que mon principal problème pourrait être: Comment connaître le nom du fichier JAR où ma classe principale vies?
Certes, j'ai pu le lire à l'aide de java.util.Zip
.
Ma Structure est comme ceci:
Ils sont comme:
my.jar!/Main.class
my.jar!/Aux.class
my.jar!/Other.class
my.jar!/images/image01.png
my.jar!/images/image02a.png
my.jar!/images/imwge034.png
my.jar!/images/imagAe01q.png
my.jar!/META-INF/manifest
Droit maintenant, je suis en mesure de charger par exemple "images/image01.png" utilisation:
ImageIO.read(this.getClass().getResource("images/image01.png));
Mais seulement parce que je sais le nom du fichier, pour le reste, je dois charger dynamiquement.
- Juste une pensée, pourquoi ne pas zip/jar images dans un fichier séparé et de lire les entrées à partir de votre classe dans un autre pot?
- Car il aurait besoin d'un "extra" de l'étape de distribution/installation. 🙁 Vous savez, les utilisateurs finaux.
- Étant donné que vous avez créé le pot, vous pourriez aussi bien inclure la liste des fichiers qui s'y trouvent, plutôt que de tenter des trucs.
- Eh bien, je peux me tromper mais bocaux peut être incorporé à l'intérieur d'autres pots. Celui-jar(TM) de la solution d'emballage ibm.com/developerworks/java/library/j-onejar travaille sur cette base. À l'exception, dans votre cas, vous n'avez pas besoin de la capacité de charge des classes.
Vous devez vous connecter pour publier un commentaire.
Noter que dans Java 7, vous pouvez créer un
FileSystem
du POT dossier (zip), puis utilisez NIO du répertoire de la marche et des mécanismes de filtrage de recherche à travers elle. Ce serait beaucoup plus facile d'écrire du code qui gère les Pots et les "explosé" répertoires.Code qui fonctionne pour les deux IDE et .les fichiers jar:
FileSystems.newFileSystem()
prend unMap<String, ?>
, si vous avez besoin de spécifier àCollections.emptyMap()
qu'il a besoin de retourner dûment est tapé un. Cela fonctionne:Collections.<String, Object>emptyMap()
.fileSystem
!walk
méthode dansFiles
est uniquement disponible en 1.8). Le seul problème est que les ressources du répertoire s'affiche dans laFiles.walk(myPath, 1)
, pas seulement les fichiers. Je suppose que le premier élément peut être tout simplement ignoréuri.getScheme().equals("jar")
?myPath = fileSystem.getPath("/resources");
ne fonctionne pas pour moi; il n'a pas trouver quoi que ce soit. Il doit être "images" dans mon cas, et les "images"-répertoire est certainement inclus dans mon bocal!erickson réponse a parfaitement fonctionné:
Voici le code de travail.
Et je viens de modifier ma méthode de chargement à partir de ce:
À ceci:
Je voudrais élargir sur acheron55 de réponse, car c'est un non-solution sûre, pour plusieurs raisons:
FileSystem
objet.FileSystem
objet existe déjà.C'est un peu une solution plus sûre:
Il n'y a pas de réel besoin pour synchroniser le nom du fichier; on pourrait simplement synchroniser sur le même objet à chaque fois (ou faire de la méthode
synchronized
), c'est purement une optimisation.Je dirais que c'est encore une problématique de la solution, car il pourrait y avoir d'autres parties du code qui utilise la
FileSystem
interface sur les mêmes fichiers, et il pourrait interférer avec eux (même dans un seul thread de l'application).Aussi, elle ne vérifie pas pour
null
s (par exemple, surgetClass().getResource()
.Ce Java NIO interface est une sorte d'horrible, car il introduit un global/singleton non thread-safe de ressources, et sa documentation est extrêmement vague (beaucoup d'inconnues dus au fournisseur spécifiques mises en œuvre). Les résultats peuvent varier pour d'autres
FileSystem
fournisseurs (pas de POT). Peut-être il ya une bonne raison pour qu'il soit ainsi; je ne sais pas, je n'ai pas étudié les implémentations.En supposant que votre projet est emballé dans un Bocal (pas forcément vrai!), vous pouvez utiliser le chargeur de classe.getResource() ou findResource() avec le nom de la classe suivi .classe) pour obtenir le pot qui contient une classe donnée. Vous aurez à analyser le pot de nom à partir de l'URL qui revient (pas difficile), que je vais le laisser comme un exercice pour le lecteur 🙂
Assurez-vous de tester pour le cas où la classe ne fait pas partie d'un bocal.
CodeSource
.Voici une méthode que j'ai écrit pour un "exécuter tous les JUnits en vertu d'un package". Vous devriez être capable de l'adapter à vos besoins.
Edit:
Ah, dans ce cas, vous pourriez voulez que cet extrait que bien (même cas d'utilisation 🙂 )
Un fichier jar est juste un fichier zip avec un structurés manifeste. Vous pouvez ouvrir le fichier jar avec l'habitude java zip outils et analyse le contenu du fichier de cette façon, gonfler les ruisseaux, etc. Utilisez-la dans un getResourceAsStream appel, et il convient à tous les hunky dory.
MODIFIER /après clarification
Il m'a fallu une minute pour se souvenir de tous les morceaux et je suis sûr qu'il y a de plus propre à en faire, mais je voulais voir que je n'étais pas folle. Dans mon projet image.jpg est un fichier d'une certaine partie du fichier jar. Je reçois le chargeur de classe de la classe principale (SomeClass est le point d'entrée) et l'utiliser pour découvrir la image.jpg de la ressource. Puis certains flux de magie pour le faire entrer dans cette ImageInputStream chose et tout va bien.
new File("blah.JAR")
pour créer un Fichier objet qui représente le POT, par exemple. Il suffit de remplacer "blah.JAR" avec le nom de votre POT.Donné un véritable fichier JAR, vous pouvez lister le contenu à l'aide de
JarFile.entries()
. Vous aurez besoin de connaître l'emplacement du fichier JAR, vous ne pouvez pas demander le chargeur de classe de la liste de tout ce qu'il pouvait m'atteindre.Vous devriez être en mesure de travailler sur l'emplacement du fichier JAR à partir de l'URL renvoyée à partir de
ThisClassName.class.getResource("ThisClassName.class")
, mais il peut être un petit peu délicate.new File("baz.jar)
, le Fichier a pour but de représenter votre fichier JAR.new JarFile(new File(ThisClassName.class.getProtectionDomain().getCodeSource().getLocation().toURI())).entries()
Il y a quelques temps j'ai fait une fonction qui récupère classess de l'intérieur de POT:
Voici un exemple d'utilisation de Réflexions bibliothèque pour analyser récursivement classpath par regex modèle de nom augmentée avec un couple de Goyave des avantages afin de récupérer des ressources de contenu:
Cela fonctionne avec les deux pots et des vues éclatées des classes.
J'ai porté acheron55 réponse de Java 7 et fermé le
FileSystem
objet. Ce code fonctionne dans l'IDE, dans les fichiers jar et dans un bocal à l'intérieur d'une guerre sur Tomcat 7; mais notez qu'il ne pas travail dans un bocal à l'intérieur d'une guerre sur JBoss 7 (il donneFileSystemNotFoundException: Provider "vfs" not installed
, voir aussi ce post). En outre, comme le code d'origine, il n'est pas thread-safe, comme suggéré par euh. Pour ces raisons, j'ai abandonné cette solution; cependant, si vous pouvez accepter ces questions, voici mon prêt-à-code:Il y a deux très utilitaires, tous deux appelés JarScan:
http://www.inetfeedback.com/jarscan
jarscan.dev.java.net
Voir aussi cette question: JarScan, analyser tous les fichiers JAR dans tous les sous-dossiers pour la classe spécifique
Juste une autre façon d'inscription/lecture de fichiers à partir d'un pot de l'URL et il le fait de manière récursive pour imbriquée pots
https://gist.github.com/trung/2cd90faab7f75b3bcbaa