Вопрос-ответ

How to find files that match a wildcard string in Java?

Как найти файлы, соответствующие подстановочной строке в Java?

Это должно быть действительно просто. Если у меня есть строка, подобная этой:

../Test?/sample*.txt

тогда каков общепринятый способ получения списка файлов, соответствующих этому шаблону? (например, он должен соответствовать ../Test1/sample22b.txt и ../Test4/sample-spiffy.txt, но не ../Test3/sample2.blah or ../Test44/sample2.txt)

Я взглянул на org.apache.commons.io.filefilter.WildcardFileFilter и это кажется правильным решением, но я не уверен, как использовать его для поиска файлов в относительном пути к каталогу.

Я полагаю, я могу поискать источник для ant, поскольку он использует синтаксис подстановочных знаков, но я, должно быть, упускаю здесь что-то довольно очевидное.

(редактировать: приведенный выше пример был всего лишь примером. Я ищу способ анализа общих путей, содержащих подстановочные знаки, во время выполнения. Я понял, как это сделать, основываясь на предложении mmyers, но это немного раздражает. Не говоря уже о том, что java JRE, похоже, автоматически разбирает простые подстановочные знаки в аргументах main (String[]) из одного аргумента, чтобы "сэкономить" мне время и хлопоты... Я просто рад, что у меня не было нефайловых аргументов в наборе.)

Переведено автоматически
Ответ 1

Попробуйте FileUtils из Apache commons-io (listFiles и iterateFiles методы):

File dir = new File(".");
FileFilter fileFilter = new WildcardFileFilter("sample*.java");
File[] files = dir.listFiles(fileFilter);
for (int i = 0; i < files.length; i++) {
System.out.println(files[i]);
}

Чтобы решить вашу проблему с TestX папками, я бы сначала перебрал список папок:

File[] dirs = new File(".").listFiles(new WildcardFileFilter("Test*.java");
for (int i=0; i<dirs.length; i++) {
File dir = dirs[i];
if (dir.isDirectory()) {
File[] files = dir.listFiles(new WildcardFileFilter("sample*.java"));
}
}

Довольно грубое решение, но должно работать нормально. Если это не соответствует вашим потребностям, вы всегда можете использовать RegexFileFilter.

Ответ 2

Рассмотрим DirectoryScanner от Apache Ant:

DirectoryScanner scanner = new DirectoryScanner();
scanner.setIncludes(new String[]{"**/*.java"});
scanner.setBasedir("C:/Temp");
scanner.setCaseSensitive(false);
scanner.scan();
String[] files = scanner.getIncludedFiles();

Вам потребуется ссылка ant.jar (~ 1,3 МБ для ant 1.7.1).

Ответ 3

Вот примеры перечисления файлов по шаблону на основе Java 7 nio глобализацией и Java 8 lambdas:

    try (DirectoryStream<Path> dirStream = Files.newDirectoryStream(
Paths.get(".."), "Test?/sample*.txt")) {
dirStream.forEach(path -> System.out.println(path));
}

или

    PathMatcher pathMatcher = FileSystems.getDefault()
.getPathMatcher("regex:Test./sample\\w+\\.txt");
try (DirectoryStream<Path> dirStream = Files.newDirectoryStream(
new File("..").toPath(), pathMatcher::matches)) {
dirStream.forEach(path -> System.out.println(path));
}
Ответ 4

Начиная с Java 8, вы можете использовать Files#find метод непосредственно из java.nio.file.

public static Stream<Path> find(Path start,
int maxDepth,
BiPredicate<Path, BasicFileAttributes> matcher,
FileVisitOption... options)

Пример использования

Files.find(startingPath,
Integer.MAX_VALUE,
(path, basicFileAttributes) -> path.toFile().getName().matches(".*.pom")
);

Или пример помещения элементов в простую коллекцию строк:

import java.io.UncheckedIOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collection;
import java.util.stream.Stream;

final Collection<String> simpleStringCollection = new ArrayList<>();

String wildCardValue = "*.txt";

final Path dir = Paths.get(".");

try {
Stream<Path> results = Files.find(dir,
Integer.MAX_VALUE,
(path, basicFileAttributes) -> path.toFile().getName().matches(wildCardValue)
);

results.forEach(p -> simpleStringCollection.add(p.toString()));
} catch (IOException e) {
throw new UncheckedIOException(e);
}
java file