To powinno być naprawdę proste. Jeśli mam taki ciąg:
../Test?/sample*.txt
w takim razie jaki jest ogólnie akceptowany sposób uzyskania listy plików pasujących do tego wzorca? (np powinna pasować ../Test1/sample22b.txt
i ../Test4/sample-spiffy.txt
ale nie ../Test3/sample2.blah
lub ../Test44/sample2.txt
)
Przyjrzałem się i wygląda na org.apache.commons.io.filefilter.WildcardFileFilter
to, że jest to właściwa bestia, ale nie jestem pewien, jak go użyć do wyszukiwania plików w względnej ścieżce katalogu.
Przypuszczam, że mogę poszukać źródła mrówki, ponieważ używa ona składni symboli wieloznacznych, ale chyba brakuje mi tutaj czegoś dość oczywistego.
( edycja : powyższy przykład to tylko przykładowy przypadek. Szukam sposobu na przeanalizowanie ogólnych ścieżek zawierających symbole wieloznaczne w czasie wykonywania. Zorientowałem się, jak to zrobić na podstawie sugestii mmyersów, ale jest to trochę denerwujące. Nie wspominając o tym) JRE java wydaje się automatycznie analizować proste symbole wieloznaczne w głównym (argumenty String []) z pojedynczego argumentu, aby "zaoszczędzić" czas i kłopoty ... Cieszę się, że nie mam argumentów niebędących plikami w mieszać.)
Odpowiedzi:
Rozważ DirectoryScanner z Apache Ant:
Będziesz musiał odwołać się do ant.jar (~ 1,3 MB dla ant 1.7.1).
źródło
DirectoryScanner
to samo można znaleźć w plexus-utils (241Kb). Który jest mniejszy niżant.jar
(1,9 Mb).ls
z tym samym wzorcem pliku (milisekundy wls <pattern>
porównaniu z minutami podczas korzystania z DirectoryScanner) ...Wypróbuj
FileUtils
z Apache commons-io (listFiles
iiterateFiles
metody):Aby rozwiązać problem z
TestX
folderami, najpierw przejrzałbym listę folderów:Całkiem rozwiązanie typu „brutalna siła”, ale powinno działać dobrze. Jeśli to nie odpowiada Twoim potrzebom, zawsze możesz użyć RegexFileFilter .
źródło
Oto przykłady listowania plików według wzorca obsługiwanego przez globbing Java 7 nio i lambdy Java 8:
lub
źródło
Files.walk(Paths.get("..")).filter(matcher::matches).forEach(System.out::println);
Możesz przekonwertować swój ciąg znaków wieloznacznych na wyrażenie regularne i użyć go z
matches
metodą String . Idąc za twoim przykładem:To działa dla twoich przykładów:
I kontrprzykłady:
źródło
?
public static boolean isFileMatchTargetFilePattern (final File f, final String targetPattern) {`` String regex = targetPattern.replace (".", "\\."); `regex = regex.replace("?", ".?").replace("
*", ".
*");
return f.getName().matches(regex);
}
StringBuffer regexBuffer = ...; Matcher matcher = Pattern.compile("(.*?)([*?])").matcher(original); while (matcher.find()) { matcher.appendReplacement(regexBuffer, (Pattern.quote(matcher.group(1)) + (matcher.group(2).equals("*") ? ".*?" : ".?")).replace("\\", "\\\\").replace("$", "\\$")); } matcher.appendTail(regexBuffer);
.
zamiast.?
.Od Java 8 możesz używać
Files#find
metody bezpośrednio zjava.nio.file
.Przykładowe użycie
źródło
Może ci to teraz nie pomóc, ale JDK 7 ma dopasować nazwy plików glob i wyrażeń regularnych w ramach „Więcej funkcji NIO”.
źródło
Biblioteka symboli wieloznacznych wydajnie dopasowuje zarówno nazwy plików glob, jak i wyrażeń regularnych:
http://code.google.com/p/wildcard/
Wdrożenie jest zwięzłe - JAR ma tylko 12,9 kilobajta.
źródło
Prostym sposobem bez użycia zewnętrznego importu jest użycie tej metody
Utworzyłem pliki csv o nazwach billing_201208.csv, billing_201209.csv, billing_201210.csv i wygląda na to, że działają dobrze.
Dane wyjściowe będą następujące, jeśli pliki wymienione powyżej istnieją
źródło
Jak napisano w innej odpowiedzi, biblioteka symboli wieloznacznych działa zarówno w przypadku dopasowywania nazw plików glob, jak i wyrażeń regularnych: http://code.google.com/p/wildcard/
Użyłem następującego kodu, aby dopasować wzorce glob, w tym bezwzględne i względne w systemach plików w stylu * nix:
Spędziłem trochę czasu próbując uzyskać metody FileUtils.listFiles w bibliotece Apache commons io (zobacz odpowiedź Vladimira), aby to zrobić, ale bez powodzenia (teraz zdaję sobie sprawę / myślę, że może obsługiwać tylko wzorce pasujące do jednego katalogu lub pliku na raz) .
Dodatkowo, użycie filtrów wyrażeń regularnych (patrz odpowiedź Fabiana) do przetwarzania dowolnych wzorców glob typu absolutnego dostarczonych przez użytkownika bez przeszukiwania całego systemu plików wymagałoby pewnego wstępnego przetworzenia dostarczonego globu w celu określenia największego prefiksu innego niż wyrażenia regularne / glob.
Oczywiście Java 7 może ładnie obsłużyć żądaną funkcjonalność, ale niestety na razie utknąłem w Javie 6. Biblioteka jest stosunkowo malutka i ma rozmiar 13,5 kb.
Uwaga dla recenzentów: próbowałem dodać powyższe do istniejącej odpowiedzi wspominającej o tej bibliotece, ale zmiana została odrzucona. Nie mam wystarczającej liczby przedstawicieli, aby dodać to jako komentarz. Czy nie ma lepszego sposobu ...
źródło
Powinieneś być w stanie użyć
WildcardFileFilter
. Po prostu użyj,System.getProperty("user.dir")
aby uzyskać katalog roboczy. Spróbuj tego:Nie powinieneś zastępować
*
go[.*]
, zakładając, że używany jest filtr wieloznacznyjava.regex.Pattern
. Nie testowałem tego, ale stale używam wzorców i filtrów plików.źródło
Glob of Java7: Finding Files . ( Próbka )
źródło
Filtr Apache jest zbudowany w celu iteracji plików w znanym katalogu. Aby zezwolić na używanie symboli wieloznacznych również w katalogu, musisz podzielić ścieżkę na „
\
” lub „/
” i wykonać filtr dla każdej części osobno.źródło
Dlaczego nie użyć, zrób coś takiego:
Wtedy nie będziesz musiał martwić się o ścieżki względne i w razie potrzeby możesz użyć symboli wieloznacznych.
źródło
Zaimplementuj interfejs JDK FileVisitor. Oto przykład http://wilddiary.com/list-files-matching-a-naming-pattern-java/
źródło
Metoda użytkowa:
Test jUnit:
Wynik:
źródło
foo/bar.txt
pasujefoo?bar.txt
i to nie jest poprawne../Test?/sample*.txt
źródło