tags:

views:

93

answers:

6

I have a directory, C:\myDir.

under this directory, there may be folders and various files

How can I "loop" through this directory and build up a File array of all files with a .properties extension?

I want to do some processing on these files, the reason for a File[] is to keep it dynamic (so additional properties files added in the future will be included)

I'm hoping to do something like this :

public static void main (String[] vargs)
{

   // find all .properties files
   //

   //loop through property file and process
   {
      doSomething(myFile[i]);
   }

}

public void doSomething(File myfile) {}
+2  A: 

Using commons-io FilenameUtils

final File dir = new File("c:\\myDir");
final File[] files = dir.listFiles(new FilenameFilter() {
    @Override
    public boolean accept(final File dir, final String name) {
        return FilenameUtils.isExtension(name, "properties");
    }
});
Jon Freedman
+4  A: 

You can use Apache Commons IO FileUtils class for it.

FileUtils.listFiles(File directory, String[] extensions, boolean recursive);

Hope this helps.

Ankit
+9  A: 

Look at FilenameFilter.

final FilenameFilter filter = new FilenameFilter() {
      public boolean accept(final File directory, final String name) {
        return name.endsWith(".properties");
      }
};
JRL
A strong +1 for showing the only answer (so far) that *does not* recommend another library for this basic task. `File.listFiles(FilenameFilter filter)` is there since Java 1.2
Andreas_D
The question asks about finding files _under_ a directory, not _in_ a directory.
Brian Harris
@Brian: I don't see the difference, but even if there was, hardly worth a downvote, don't you think?
JRL
@JRL: The difference is that "under" implies a recursive search whereas "in" does not.
Brian Harris
I was responding to Andreas_D's comment which mentions File.listFiles, by the way.
Brian Harris
+1  A: 

Apache commons IO has a nice class for traversing file systems called DirectoryWalker. If you want to find these properties files recursively, check it out.

For example, the below code will recursively find image files under a directory and return them as a List.

import com.google.common.collect.Lists;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
import org.apache.commons.io.DirectoryWalker;
import org.apache.commons.io.IOCase;
import org.apache.commons.io.filefilter.AndFileFilter;
import org.apache.commons.io.filefilter.DirectoryFileFilter;
import org.apache.commons.io.filefilter.HiddenFileFilter;
import org.apache.commons.io.filefilter.IOFileFilter;
import org.apache.commons.io.filefilter.NotFileFilter;
import org.apache.commons.io.filefilter.OrFileFilter;
import org.apache.commons.io.filefilter.PrefixFileFilter;
import org.apache.commons.io.filefilter.SuffixFileFilter;

class SourceImageFinder extends DirectoryWalker {

    public SourceImageFinder() {
        // visible directories and image files
        super(new AndFileFilter(notHiddenFileFilter(), new OrFileFilter(imageFileFilter(), DirectoryFileFilter.INSTANCE)), -1);
    }

    public List<File> findSourceImages(File directory) {
        List<File> results = Lists.newArrayList();
        try {
            walk(directory, results);
        } catch (IOException ex) {
            throw new RuntimeException("Problem finding images", ex);
        }
        return results;
    }

    @Override
    protected void handleFile(File file, int depth, Collection results) throws IOException {
        results.add(file);
    }

    private static IOFileFilter notHiddenFileFilter() {
        // HiddenFileFilter.HIDDEN doesn't exclude files starting with '.' on Windows but I want to.
        return new NotFileFilter(new OrFileFilter(HiddenFileFilter.HIDDEN, new PrefixFileFilter(".")));
    }

    private static IOFileFilter imageFileFilter() {
        return new SuffixFileFilter(new String[]{"png", "jpg", "jpeg", "gif", "bmp", "tif", "tiff"}, IOCase.INSENSITIVE);
    }
}
Brian Harris
You can get rid of many of these new BlaFilter() calls by adding the static import `import static org.apache.commons.io.filefilter.FileFilterUtils.*` and using factory methods like `andFileFilter()`, `notFileFilter()` etc
seanizer
Sweet, free code review. Thanks!
Brian Harris
+2  A: 

Implemented code which returns files recursing into directories.

import java.io.File;
import java.util.ArrayList;
import java.util.List;


public class FileList {
    public static void main(String[] args) {
        File dir = new File("/usr/local/work_apps");

        String filterExt = "properties";

        List<File> fileList = new ArrayList<File>();

        getFileteredFiles(dir,filterExt,fileList);

        for (File file : fileList) {
            System.out.println("FileList.main() "+file.getName());
        }

    }

    /**
     * Get files recursively filtered by file extention.
     * @param dir search directory for.
     * @param filterExt file extention filter.
     * @param fileList List passed to method to be filled with file's.
     */
    public static  void getFileteredFiles(File dir,String filterExt,List<File> fileList){

        if(dir.isDirectory()){
            File[] files = dir.listFiles();
            if(files != null && files.length > 0){
            for (File file : files) {
                if(file.isDirectory()){
                    getFileteredFiles(file, filterExt, fileList);
                }else{
                    if(file.getName().endsWith("."+filterExt)){
                        fileList.add(file);
                    }
                }
            }
            }
        }

    }

}
YoK
Simplest example-answer so far, but it doesn't seem to search recursively on directories :(
James.Elsey
@James.Elsey Changed my code to search recursively on directories :). This code is actually more simple.
YoK
Yes, but a) you are creating a new List for each subdirectory, b) you are returning an implementation not an interface from your method (tying the client to variables of type ArrayList instead of List) and c) you can not configure what you are looking for (what if you want .txt or .xml instead?)
seanizer
@seanizer changed my code. Now its also handling what you asked for.
YoK
+1 Now it's very elegant, you are using only one method, cool. The only thing that still bothers me is the misspelled method name (should be filtered, not filetered)
seanizer
Obviously, you are unaware of two interfaces available with java io package, the FilenameFilter and FileFilter
naikus
@naikus I had given solution using FilenameFilter, but that didn't recurse through directories :).
YoK
@YoK, you could use FilenameFilter or FileFilter and still recurse into directories
naikus
+1  A: 

Here is a complete answer without external libs:

public class FileFinder{

    public static List<File> findFiles(final File baseDir, final String regex){
        final List<File> files = new ArrayList<File>();

        scanFolder(baseDir, Pattern.compile(regex), files);
        return files;
    }

    private static void scanFolder(final File dir,
        final Pattern pattern,
        final List<File> files){

        for(final File candidate : dir.listFiles()){
            if(candidate.isDirectory()){
                scanFolder(candidate, pattern, files);
            } else if(pattern.matcher(candidate.getName()).matches()){
                files.add(candidate);
            }
        }
    }

}

Call it like this:

public static void main(String[] args){
    List<File> filesAsList = FileFinder.findFiles(
                                new File("c:\\my\\dir"), ".*\\.properties");
    File[] filesAsArray = filesAsList.toArray(new File[filesAsList.size()]);
}
seanizer