Szukam sposobu na uzyskanie listy wszystkich nazw zasobów z danego katalogu ścieżki klas, coś w rodzaju metody List<String> getResourceNames (String directoryName)
.
Na przykład, biorąc pod uwagę katalog ścieżce klasy x/y/z
zawierający pliki a.html
, b.html
, c.html
oraz podkatalog d
, getResourceNames("x/y/z")
powinien zwrócić List<String>
zawierające następujące ciągi: ['a.html', 'b.html', 'c.html', 'd']
.
Powinien działać zarówno dla zasobów w systemie plików, jak i słoikach.
Wiem, że mogę napisać krótki urywek za pomocą File
s, JarFile
s i URL
s, ale nie chcę wymyślać koła ponownie. Moje pytanie brzmi: biorąc pod uwagę istniejące publicznie dostępne biblioteki, jaki jest najszybszy sposób wdrożenia getResourceNames
? Możliwe są stosy wiosenne i Apache Commons.
Odpowiedzi:
Niestandardowy skaner
Zaimplementuj własny skaner. Na przykład:
Spring Framework
Użyj
PathMatchingResourcePatternResolver
z Spring Framework.Ronmamo Refleksje
Inne techniki mogą być powolne w czasie wykonywania dla ogromnych wartości CLASSPATH. Szybszym rozwiązaniem jest użycie interfejsu API Reflections ronmamo , który wstępnie kompiluje wyszukiwanie w czasie kompilacji.
źródło
new Reflections("my.package", new ResourcesScanner()).getResources(pattern)
getResourceAsStream()
z względną ścieżką do katalogu prowadzi do FileInputStream (File), który jest zdefiniowany w celu zgłaszania wyjątku FileNotFoundException, jeśli plik jest katalogiem.Oto kod
Źródło : forums.devx.com/showthread.php?t=153784
Jeśli używasz Spring Spójrz na PathMatchingResourcePatternResolver
źródło
File.pathSeparator
zamiast metody:
na stałe zakodowanejgetResources
.final String[] classPathElements = classPath.split(System.pathSeparator);
Korzystanie z odbić
Uzyskaj wszystko na ścieżce klas:
Kolejny przykład - pobierz wszystkie pliki z rozszerzeniem .csv z some.package :
źródło
Jeśli używasz apache commonsIO, możesz użyć dla systemu plików (opcjonalnie z filtrem rozszerzeń):
a dla zasobów / ścieżki klasy:
Jeśli nie wiesz, czy „directoy /” znajduje się w systemie plików lub zasobach, możesz dodać plik
lub
przed połączeniami i używaj obu w połączeniu ...
źródło
Jeśli chodzi o PathMatchingResourcePatternResolver, to jest to, czego potrzeba w kodzie:
źródło
classpath*:config/*.xml
W
Spring framework
„sPathMatchingResourcePatternResolver
jest naprawdę niesamowite dla tych rzeczy:Zależność od Maven:
źródło
Użyłem kombinacji odpowiedzi Roba.
źródło
/' or
”lub./
żaden z nich faktycznie nie działałZ wiosną jest to łatwe. Niezależnie od tego, czy jest to plik, folder, czy nawet wiele plików, istnieje szansa, że możesz to zrobić przez wstrzyknięcie.
Ten przykład pokazuje wstrzyknięcie wielu plików znajdujących się w
x/y/z
folderze.Działa dla zasobów w systemie plików, a także w plikach JAR.
źródło
To powinno zadziałać (jeśli wiosna nie jest opcją):
źródło
Mój sposób, bez sprężyny, używany podczas testu jednostkowego:
źródło
Najsolidniejszym mechanizmem wyświetlania wszystkich zasobów w ścieżce klasy jest obecnie użycie tego wzorca z ClassGraph , ponieważ obsługuje on możliwie najszerszą gamę mechanizmów specyfikacji ścieżki klasy , w tym nowy system modułów JPMS. (Jestem autorem ClassGraph.)
źródło
Myślę, że możesz to zrobić przy użyciu [ Zip System System Provider ] [1]. Podczas używania
FileSystems.newFileSystem
wygląda na to, że możesz traktować obiekty w tym pliku ZIP jako „zwykły” plik.W powiązanej dokumentacji powyżej:
Dokumentacja
jdk.zipfs
modułu w [stanach Java 11] [5]:Oto wymyślony przykład, który wykorzystałem przy użyciu przykładowych zasobów. Zauważ, że a
.zip
jest a.jar
, ale możesz dostosować swój kod, aby zamiast tego używał zasobów ścieżki klasy:Ustawiać
Jawa
Wynik
źródło
Żadna z odpowiedzi nie działała dla mnie, mimo że moje zasoby zostały umieszczone w folderach zasobów i postępowałem zgodnie z powyższymi odpowiedziami. Co zrobiło lewę to:
źródło
Na podstawie powyższych informacji @rob stworzyłem implementację, którą wypuszczam do domeny publicznej:
Chociaż nie spodziewałbym
getResourcesAsStream
się, że będę tak działać w katalogu, to naprawdę działa i działa dobrze.źródło