Ich suche nach einer Möglichkeit, eine Liste aller Ressourcennamen aus einem bestimmten Klassenpfadverzeichnis abzurufen, ähnlich einer Methode List<String> getResourceNames (String directoryName)
.
Um zum Beispiel ein Classpath - Verzeichnis angegeben x/y/z
enthält Dateien a.html
, b.html
, c.html
und ein Unterverzeichnis d
, getResourceNames("x/y/z")
sollte zurückgeben eine List<String>
der folgenden Zeichenketten enthalten: ['a.html', 'b.html', 'c.html', 'd']
.
Es sollte sowohl für Ressourcen im Dateisystem als auch für Jars funktionieren.
Ich weiß, dass ich mit File
s, JarFile
s und URL
s einen kurzen Ausschnitt schreiben kann , aber ich möchte das Rad nicht neu erfinden. Meine Frage ist angesichts der vorhandenen öffentlich verfügbaren Bibliotheken, wie diese am schnellsten implementiert werden kann getResourceNames
. Spring- und Apache Commons-Stapel sind beide machbar.
Antworten:
Benutzerdefinierter Scanner
Implementieren Sie Ihren eigenen Scanner. Beispielsweise:
Frühlingsrahmen
Verwendung
PathMatchingResourcePatternResolver
aus Spring Framework.Ronmamo Reflexionen
Die anderen Techniken können zur Laufzeit für große CLASSPATH-Werte langsam sein. Eine schnellere Lösung ist die Verwendung der Reflections-API von ronmamo , die die Suche zur Kompilierungszeit vorkompiliert.
quelle
new Reflections("my.package", new ResourcesScanner()).getResources(pattern)
getResourceAsStream()
mit einem relativen Pfad zu einem Verzeichnis führt zu einem FileInputStream (File), der definiert ist, um FileNotFoundException auszulösen, wenn die Datei ein Verzeichnis ist.Hier ist der Code
Quelle : forums.devx.com/showthread.php?t=153784
Wenn Sie Spring verwenden, schauen Sie sich PathMatchingResourcePatternResolver an
quelle
File.pathSeparator
anstatt hartcodiert:
ingetResources
Verfahren.final String[] classPathElements = classPath.split(System.pathSeparator);
Mit Reflexionen
Holen Sie sich alles auf den Klassenpfad:
Ein weiteres Beispiel : Holen Sie sich alle Dateien mit der Erweiterung .csv aus some.package :
quelle
Wenn Sie Apache commonsIO verwenden, können Sie für das Dateisystem verwenden (optional mit Erweiterungsfilter):
und für Ressourcen / Klassenpfad:
Wenn Sie nicht wissen, ob sich "directoy /" im Dateisystem oder in Ressourcen befindet, können Sie a hinzufügen
oder
vor den Anrufen und verwenden Sie beide in Kombination ...
quelle
In Bezug auf den PathMatchingResourcePatternResolver wird im Code Folgendes benötigt:
quelle
classpath*:config/*.xml
Die
Spring framework
‚sPathMatchingResourcePatternResolver
ist wirklich genial für diese Dinge:Maven-Abhängigkeit:
quelle
Verwendete eine Kombination aus Robs Antwort.
quelle
/' or
.` oder./
keine davon hat tatsächlich funktioniertMit Spring ist es einfach. Sei es eine Datei oder ein Ordner oder sogar mehrere Dateien, es besteht die Möglichkeit, dass Sie dies per Injektion tun können.
Dieses Beispiel zeigt das Einfügen mehrerer Dateien im
x/y/z
Ordner.Es funktioniert sowohl für Ressourcen im Dateisystem als auch in JARs.
quelle
Dies sollte funktionieren (wenn der Frühling keine Option ist):
quelle
Mein Weg, keine Feder, während eines Unit-Tests verwendet:
quelle
Der robusteste Mechanismus zum Auflisten aller Ressourcen im Klassenpfad ist derzeit die Verwendung dieses Musters mit ClassGraph , da es die größtmögliche Anzahl von Klassenpfadspezifikationsmechanismen verarbeitet , einschließlich des neuen JPMS-Modulsystems. (Ich bin der Autor von ClassGraph.)
quelle
Ich denke, Sie können den [ Zip File System Provider ] [1] nutzen, um dies zu erreichen. Wenn
FileSystems.newFileSystem
Sie es verwenden, können Sie die Objekte in dieser ZIP-Datei als "normale" Datei behandeln.In der oben verlinkten Dokumentation:
Die Dokumentation für das
jdk.zipfs
Modul in [Java 11-Zustände] [5]:Hier ist ein erfundenes Beispiel, das ich mit Ihren Beispielressourcen erstellt habe. Beachten Sie, dass a a
.zip
ist.jar
, aber Sie können Ihren Code anpassen, um stattdessen Klassenpfadressourcen zu verwenden:Konfiguration
Java
Ausgabe
quelle
Keine der Antworten funktionierte für mich, obwohl ich meine Ressourcen in Ressourcenordnern abgelegt hatte und den obigen Antworten folgte. Was einen Trick machte, war:
quelle
Basierend auf den obigen Informationen von @rob habe ich die Implementierung erstellt, die ich öffentlich zugänglich mache:
Ich hätte zwar nicht erwartet
getResourcesAsStream
, dass es in einem Verzeichnis so funktioniert, aber es funktioniert wirklich und es funktioniert gut.quelle