views:

217

answers:

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

As you can see, the code is dirty with "||"

Do you know how to make it better?

+4  A: 

Why not use regular expressions?

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

and then return p.matcher(name).find();

alamar
Or even easier, use a regular expression with String#matches, like name.matches(".*?\\.(zip|jar|z|gz)$").
Fabian Steeg
File system traverse is one of a few places where it would be useful to harness perfomance boost from pre-compiled patterns.
alamar
A: 

You could statically create a map, and return true if the filename extension is a key in the map.

Or you could try to match the filename against a regular expression (but I'd choose to use a map instead).

Dave Hinton
+2  A: 

Some pseudocode solutions:

Iterate over an array

suffixes = [".tar", ".zip", ".jpg"]

for suffix in suffixes:
    if name.endsWith(suffix):
        return True

Use a set

suffixes = [".tar", ".zip", ".jpg"]

nameSuffix = name.getSuffix()
if nameSuffix in suffixes:
    return True
Georg
+1 for using a Set.
Mark
+6  A: 

With Java 6, this is a perfect case for a FileNameExtensionFilter... except that it extends javax.swing.filechooser.FileFilter instead of implementing java.io.FileFilter.
But it is trivial to write a wrapper for it:

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);
    }
});
Michael Myers
+1  A: 

I just finished writing this class:

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

usage:

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

BTW this is a reusable class, you can even wrap it with additional checks using the decorator patter, etc.

PS

just noticed the existence of FileNameExtensionFilter

dfa
+1  A: 

You could do the following using a statically initialized HashSet. Personally I'd pull the allowed extensions out into some sort of configuration file to make it a bit easier to change, but you don't have to.

n.b. FilenameUtils belongs to Commons I/O which also includes a bunch of classes that make doing this kind of stuff easier. Take a look at FileFilterUtils as well, which simplifies things even further and provides some nice helper methods.

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

You can find the API here:

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

Jon
FileNameUtils.getExtension(fileName) is very handy
dfa
A: 

Here's my approach. java.lang.Collections is really a nice class! And because we're looking up the given file extension in a HashSet, it's more performant. Although I doubt, that performance really matters in this case ...

// ...

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('.')));

    }
});

// ...
Andreas_D