Existe-t-il une meilleure façon de faire FileFilter pour beaucoup d’extensions?

File files[] = rootDir.listFiles(new FileFilter() { public boolean accept(File file) { if (file.isDirectory()) return true; Ssortingng 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; } }); 

Comme vous pouvez le constater, le code est sale avec “||”

Savez-vous comment améliorer les choses?

Avec Java 6 ou supérieur, il s’agit d’un cas parfait pour FileNameExtensionFilter … sauf qu’il étend javax.swing.filechooser.FileFilter au lieu de java.io.FileFilter .
Mais il est sortingvial d’écrire un wrapper pour cela:

 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); } }); 

Pourquoi ne pas utiliser des expressions régulières?

static final Pattern p = Pattern.comstack("\\.(zip|jar|z|gz)$");

puis return p.matcher(name).find();

Quelques solutions de pseudocodes:

Itérer sur un tableau

 suffixes = [".tar", ".zip", ".jpg"] for suffix in suffixes: if name.endsWith(suffix): return True 

Utiliser un ensemble

 suffixes = [".tar", ".zip", ".jpg"] nameSuffix = name.getSuffix() if nameSuffix in suffixes: return True 

Je viens juste de finir d’écrire ce cours:

 class FileExtensionFilter implements FileFilter { private final Ssortingng[] validExtensions; public FileExtensionFilter(Ssortingng... validExtensions) { this.validExtensions = validExtensions; } public boolean accept(File pathname) { if (pathname.isDirectory()) { return true; } Ssortingng name = pathname.getName().toLowerCase(); for (Ssortingng ext : validExtensions) { if (name.endsWith(ext)) { return true; } } return false; } } 

usage:

 File files[] = directory.listFiles( new FileExtensionFilter(".zip", ".jar", ".z", ".tar")); 

BTW c’est une classe réutilisable, vous pouvez même l’envelopper avec des contrôles supplémentaires en utilisant le motif décorateur, etc.

PS

vient de remarquer l’existence de FileNameExtensionFilter

Vous pouvez faire ce qui suit en utilisant un HashSet initialisé statiquement. Personnellement, j’insérerais les extensions autorisées dans une sorte de fichier de configuration pour le rendre un peu plus facile à modifier, mais ce n’est pas obligatoire.

nb FilenameUtils appartient à Commons I / O, qui comprend également un ensemble de classes qui facilitent ce type de travail. Regardez également FileFilterUtils , ce qui simplifie encore les choses et fournit de bonnes méthodes d’aide.

private static Définissez allowedExtensions = null;

 static { allowedExtensions = new HashSet(); 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; Ssortingng fileName = file.getName().toLowerCase(); Ssortingng extension = FilenameUtils.getExtension(fileName); if (SsortingngUtils.isNotEmpty(extension) && allowedExtensions.contains(extension)) { return true; } else { return false; } } }); } 

Vous pouvez trouver l’API ici:

http://commons.apache.org/io/api-release/

Vous pouvez créer une carte de manière statique et renvoyer la valeur true si l’extension du nom de fichier est une clé de la carte.

Vous pouvez également essayer de faire correspondre le nom de fichier à une expression régulière (mais je choisirais plutôt d’utiliser une carte).

Voici mon approche. java.lang.Collections est vraiment une belle classe! Et comme nous recherchons l’extension de fichier donnée dans un HashSet, elle est plus performante. Bien que je doute que la performance compte vraiment dans ce cas …

 // ... final Set archives = new HashSet(); 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 Ssortingng name = file.getName().toLowerCase(); return archives.contains(name .subssortingng(name.lastIndexOf('.'))); } }); // ...