File files[] = rootDir.listFiles(new FileFilter() {
public boolean accept(File file) {
if (file.isDirectory())
return true;
String name = file.getName().toLowerCase();
if (name.endsWith(".zip") || name.endsWith(".jar")
|| name.endsWith(".z") || name.endsWith(".gz")
|| name.endsWith(".tar") || name.endsWith(".bz2")
|| name.endsWith(".bz"))
return true;
return false;
}
});
Как вы можете видеть, код грязный с "||"
Вы знаете, как сделать это лучше?
Ответ 1
С Java 6 или выше это идеальный случай для FileNameExtensionFilter
... за исключением того, что он расширяет javax.swing.filechooser.FileFilter
вместо реализация java.io.FileFilter
.
Но для него тривиально написать оболочку:
File[] files = rootDir.listFiles(new FileFilter() {
private final FileNameExtensionFilter filter =
new FileNameExtensionFilter("Compressed files",
"zip", "jar", "z", "gz", "tar", "bz2", "bz");
public boolean accept(File file) {
return filter.accept(file);
}
});
Ответ 2
Некоторые псевдокодные решения:
Итерации по массиву
suffixes = [".tar", ".zip", ".jpg"]
for suffix in suffixes:
if name.endsWith(suffix):
return True
Используйте набор
suffixes = [".tar", ".zip", ".jpg"]
nameSuffix = name.getSuffix()
if nameSuffix in suffixes:
return True
Ответ 3
Почему бы не использовать регулярные выражения?
static final Pattern p = Pattern.compile("\\.(zip|jar|z|gz)$");
а затем return p.matcher(name).find();
Ответ 4
Я только что закончил писать этот класс:
class FileExtensionFilter implements FileFilter {
private final String[] validExtensions;
public FileExtensionFilter(String... validExtensions) {
this.validExtensions = validExtensions;
}
public boolean accept(File pathname) {
if (pathname.isDirectory()) {
return true;
}
String name = pathname.getName().toLowerCase();
for (String ext : validExtensions) {
if (name.endsWith(ext)) {
return true;
}
}
return false;
}
}
использование:
File files[] = directory.listFiles(
new FileExtensionFilter(".zip", ".jar", ".z", ".tar"));
Кстати, это класс многократного использования, вы можете даже обернуть его дополнительными проверками с помощью растрата декоратора и т.д.
PS
только что заметил существование FileNameExtensionFilter
Ответ 5
Вы можете сделать следующее, используя статически инициализированный HashSet. Лично я вытащил разрешенные расширения в какой-то конфигурационный файл, чтобы сделать его немного легче изменить, но вам не нужно.
n.b. FilenameUtils относится к Commons I/O, которая также включает в себя кучу классов, которые упрощают делать подобные вещи. Взгляните на FileFilterUtils, что еще больше упрощает и предоставляет некоторые полезные вспомогательные методы.
private static Set allowedExtensions = null;
static {
allowedExtensions = new HashSet<String>();
allowedExtensions.add("txt");
allowedExtensions.add("zip");
allowedExtensions.add("jar");
allowedExtensions.add("gz");
}
public void filter() {
File rootDir = new File("/");
File files[] = rootDir.listFiles(new FileFilter() {
public boolean accept(File file) {
if (file.isDirectory()) return true;
String fileName = file.getName().toLowerCase();
String extension = FilenameUtils.getExtension(fileName);
if (StringUtils.isNotEmpty(extension)
&& allowedExtensions.contains(extension)) {
return true;
} else {
return false;
}
}
});
}
Здесь вы можете найти API:
http://commons.apache.org/io/api-release/
Ответ 6
Вы можете статически создавать карту и возвращать значение true, если расширение имени файла является ключом на карте.
Или вы можете попытаться сопоставить имя файла с регулярным выражением (но я бы выбрал вместо него карту).
Ответ 7
Вот мой подход. java.lang.Collections - действительно хороший класс! И поскольку мы просматриваем данное расширение файла в HashSet, оно более показательно. Хотя я сомневаюсь, что производительность действительно имеет значение в этом случае...
// ...
final Set<String> archives = new HashSet<String>();
Collections.addAll(archives, ".zip", ".jar", ".z", ".gz", ".tar",
".bz2", ".bz");
File files[] = rootDir.listFiles(new FileFilter() {
public boolean accept(final File file) {
if (file.isDirectory())
return true;
final String name = file.getName().toLowerCase();
return archives.contains(name
.substring(name.lastIndexOf('.')));
}
});
// ...