Использование FilenameFilter
У меня есть каталог:
File dir = new File(MY_PATH);
Я хотел бы перечислить все файлы, имя которых указано как целые числа строк, например. "10", "20". Я знаю, что должен использовать:
dir.list(FilenameFilter filter);
Как определить мой FilenameFilter
?
P.S. Я имею в виду, что имя файла может быть любой целочисленной строкой, например. "10" или "2000000" или "3452345". Нет ограничений в количестве цифр, если имя файла является целым числом.
Ответы
Ответ 1
Вы должны переопределить accept
в интерфейсе FilenameFilter
и убедитесь, что параметр name
имеет только числовые символы. Вы можете проверить это, используя matches
:
String[] list = dir.list(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.matches("[0-9]+");
}
});
Ответ 2
предпочтительно в качестве экземпляра анонимного внутреннего класса, передаваемого в качестве параметра File # list.
например, чтобы вывести список только файлов, заканчивающихся расширением .txt
:
File dir = new File("/home");
String[] list = dir.list(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.toLowerCase().endsWith(".txt");
}
});
Чтобы получить список только тех файлов, имена файлов которых представляют собой целые числа, состоящие ровно из 2 цифр, вы можете использовать следующие методы метода accept:
return name.matches("\\d{2}");
для одной или нескольких цифр:
return name.matches("\\d+");
РЕДАКТИРОВАТЬ (в ответ на комментарий @crashprophet)
Передать набор расширений файлов в список
class ExtensionAwareFilenameFilter implements FilenameFilter {
private final Set<String> extensions;
public ExtensionAwareFilenameFilter(String... extensions) {
this.extensions = extensions == null ?
Collections.emptySet() :
Arrays.stream(extensions)
.map(e -> e.toLowerCase()).collect(Collectors.toSet());
}
@Override
public boolean accept(File dir, String name) {
return extensions.isEmpty() ||
extensions.contains(getFileExtension(name));
}
private String getFileExtension(String filename) {
String ext = null;
int i = filename .lastIndexOf('.');
if(i != -1 && i < filename .length()) {
ext = filename.substring(i+1).toLowerCase();
}
return ext;
}
}
@Test
public void filefilter() {
Arrays.stream(new File("D:\\downloads").
list(new ExtensionAwareFilenameFilter("pdf", "txt")))
.forEach(e -> System.out.println(e));
}
Ответ 3
Начиная с Java 8, вы можете просто использовать лямбда-выражение для указания своего пользовательского фильтра:
dir.list((dir1, name) -> name.equals("foo"));
В приведенном выше примере, только файлы с именем "foo" будут проходить. Используйте свою собственную логику, конечно.
Ответ 4
Я делаю это как:
File folder = new File(".");
File[] listOfFiles = folder.listFiles();
for (File file : listOfFiles) {
if (file.isFile()) {
if (file.toString().endsWith(".sql")) {
System.out.println(file.getName());
}
}
}
System.out.println("End!!");
Ответ 5
Вот то, что я завел. Он использует приятное лямбда-выражение, которое можно легко превратить в ваши собственные дизайны...
File folder = new File(FullPath);
String[] files = folder.list((lamFolder, lamName) -> lamName.matches("[0-9]+"));
if(files == null) {
System.out.println("Stuff wrongly: no matching files found.");
} else {
for(String file : files) {
System.out.println("HOORAY: I found this "+ file);
}
}