Groovy (File IO): find all files and return all files - the Groovy way

14,040

Solution 1

I'd try to avoid building the collection entirely. Using closures, you can separate the logic to select the files from what you actually want to do with them, like so:

import groovy.io.FileType

def withEachTestFile(Closure closure) {
    new File("src/test/java").eachFileRecurse(FileType.FILES) {
        if (it.name =~ /Test\.java$/) {
            closure.call(it)
        }
    }
}

Then if you want to do something on the test files, you can do it directly without building up a list in memory:

withEachTestFile() { println it }

or if you really want the list, you can easily generate it, using whatever collection makes sense:

def files = []
withEachTestFile() { files << it }

Solution 2

A newer, standard and more generic way to traverse a directory which supports multiple closure callbacks is traverse.

import static groovy.io.FileType.FILES
...
def files = [] 
new File("src/test/java").traverse(type: FILES, nameFilter: ~/Test\.java$/) {
    files << it    
}

Solution 3

The following is untested, but the findAll method should help make your code very concise:

List<File> files = new File("src/test/java").listFiles().findAll { it.name =~ /Test\.java$/ }

Solution 4

something like this should work

def files = []
new File("src/test/java").eachFileRecurse(FILES) {
    if(it.name =~ /Test\.java$/)) {
        println f
        files << f
    }
}

or i think modifying your code like this

static File[] findAllTestFiles() {
    def files = []
    def directory = new File("src/test/java");
    def closure = {File f -> if(f.name =~ /Test\.java$/) {println f; files << f} }
    directory.eachFileRecurse FileType.FILES, closure
    return files;
}
Share:
14,040
gMale
Author by

gMale

Software Developer currently specializing in Android. I do a little tweeting and blogging

Updated on July 28, 2022

Comments

  • gMale
    gMale almost 2 years

    Ok, this should be easy...

    I'm new to groovy and I'm looking to implement the following logic:

    def testFiles = findAllTestFiles();
    

    So far, I've come up with the code below which successfully prints all files names. However, instead of printing, I just need to put them into a collection. Of course, I could do this the old java way: just instantiate a collection, add all the elements and return it. However, that wouldn't teach me anything.

    So how do you do this the cool, "Groovy" way?

    static File[] findAllTestFiles() {
        def directory = new File("src/test/java");
        def closure = {File f -> if(f.name =~ /Test\.java$/) println f }
        directory.eachFileRecurse FileType.FILES, closure
        return null;
    }
    

    I'm looking to implement findAlltestFiles() in Groovy using as little code as possible while still being readable.

  • gMale
    gMale over 13 years
    I feel that I really need the list of files but I'm probably wrong (since this is my first Groovy class, ever). I will consider your first suggestion more thoroughly--it seems like a great insight. I'm going to have to play with it to fully understand what you're saying and how to apply it--this is a completely different way of thinking of things! I like it... groovy is growing on me, fast.
  • gMale
    gMale over 13 years
    I've re-written my entire script, trying to design with closures in mind. At times, it still hurts my head a little to think about it, deeply. But I'm sold on Groovy so I'll get a few books and start mastering this new approach. I'm excited to learn how to use Groovy Console... thanks for your help.
  • gMale
    gMale over 13 years
    thanks! your answer was to the point and very helpful. I wish I could also award you points for the correct answer! Thanks for taking the time to help.