98

I'm looking for a way to get a list of files that match a pattern (pref regex) in a given directory.

I've found a tutorial online that uses apache's commons-io package with the following code:

Collection getAllFilesThatMatchFilenameExtension(String directoryName, String extension)
{
  File directory = new File(directoryName);
  return FileUtils.listFiles(directory, new WildcardFileFilter(extension), null);
}

But that just returns a base collection (According to the docs it's a collection of java.io.File). Is there a way to do this that returns a type safe generic collection?

skaffman
  • 398,947
  • 96
  • 818
  • 769
Omar Kooheji
  • 54,530
  • 68
  • 182
  • 238
  • why don't you just add a cast? I suppose the base collection is for compatibility reasons (with older java version). If you want to be absolutely sure, you can just create a copy and add the elements after a type check (generics are just compile time checks, anyway) – bertolami Jan 20 '10 at 16:38
  • @bertolami, don't put answers in comments. :) – lmat - Reinstate Monica Mar 16 '15 at 18:08
  • 1
    5 years after the comment was made... That's some powerful necromancy there @LimitedAtonement – Omar Kooheji Mar 16 '15 at 18:10
  • also see this link : http://stackoverflow.com/questions/16143494/search-directory-for-any-xml-file – M2E67 May 20 '16 at 06:10

6 Answers6

150

See File#listFiles(FilenameFilter).

File dir = new File(".");
File [] files = dir.listFiles(new FilenameFilter() {
    @Override
    public boolean accept(File dir, String name) {
        return name.endsWith(".xml");
    }
});

for (File xmlfile : files) {
    System.out.println(xmlfile);
}
Kevin
  • 30,111
  • 9
  • 76
  • 83
  • 3
    This means that java reads in all the files and then throws away those which don't match. Isn't this terribly slow compared to any system command which filters itself? – flaschenpost Jan 12 '15 at 17:31
  • 3
    @flaschenpost Not necessarily, as the docs make no promises about how the implementation handles caching and other performance related details. The major bound on any method of this type is the IO call down to the disk to read the file metadata. A system command would still have to read all of the same information, so it's probably close enough that it's not worth worrying about. Handling it in pure Java lets someone else handle the platform specific issues related to getting at that metadata. – Morgen Jan 15 '15 at 20:04
  • 1
    OK. I'm just used to all the languages with a `glob` method, and I expect it to run inside file system implementation and to be around 100x faster (but have not checked this). But I still have to get used to java-style, where 'fast' means seconds instead nanoseconds. ;-) – flaschenpost Jan 15 '15 at 21:00
77

Since Java 8 you can use lambdas and achieve shorter code:

File dir = new File(xmlFilesDirectory);
File[] files = dir.listFiles((d, name) -> name.endsWith(".xml"));
mr T
  • 906
  • 6
  • 8
27

Since java 7 you can the java.nio package to achieve the same result:

Path dir = ...;
List<File> files = new ArrayList<>();
try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir, "*.{java,class,jar}")) {
    for (Path entry: stream) {
        files.add(entry.toFile());
    }
    return files;
} catch (IOException x) {
    throw new RuntimeException(String.format("error reading folder %s: %s",
    dir,
    x.getMessage()),
    x);
}
Tarek
  • 3,080
  • 5
  • 38
  • 54
15

The following code will create a list of files based on the accept method of the FileNameFilter.

List<File> list = Arrays.asList(dir.listFiles(new FilenameFilter(){
        @Override
        public boolean accept(File dir, String name) {
            return name.endsWith(".exe"); // or something else
        }}));
jjnguy
  • 136,852
  • 53
  • 295
  • 323
0

What about a wrapper around your existing code:

public Collection<File> getMatchingFiles( String directory, String extension ) {
     return new ArrayList<File>()( 
         getAllFilesThatMatchFilenameExtension( directory, extension ) );
 }

I will throw a warning though. If you can live with that warning, then you're done.

OscarRyz
  • 196,001
  • 113
  • 385
  • 569
0
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.Map;
import java.util.Scanner;
import java.util.TreeMap;

public class CharCountFromAllFilesInFolder {

    public static void main(String[] args)throws IOException {

        try{

            //C:\Users\MD\Desktop\Test1

            System.out.println("Enter Your FilePath:");

            Scanner sc = new Scanner(System.in);

            Map<Character,Integer> hm = new TreeMap<Character, Integer>();

            String s1 = sc.nextLine();

            File file = new File(s1);

            File[] filearr = file.listFiles();

            for (File file2 : filearr) {
                System.out.println(file2.getName());
                FileReader fr = new FileReader(file2);
                BufferedReader br = new BufferedReader(fr);
                String s2 = br.readLine();
                for (int i = 0; i < s2.length(); i++) {
                    if(!hm.containsKey(s2.charAt(i))){
                        hm.put(s2.charAt(i), 1);
                    }//if
                    else{
                        hm.put(s2.charAt(i), hm.get(s2.charAt(i))+1);
                    }//else

                }//for2

                System.out.println("The Char Count: "+hm);
            }//for1

        }//try
        catch(Exception e){
            System.out.println("Please Give Correct File Path:");
        }//catch
    }
}
Ahmed Ashour
  • 5,179
  • 10
  • 35
  • 56