Runaider
Runaider

Reputation: 75

Java read files in folder and sub-folders

I'm making a program that changes gray-scale images to black and white images, the program has to read all .png files from folder and sub-folders and after editing them save to a new dir. Every thing worked as intended but I made some changes and the program now only reads files from the first folder or sub-folder that has images.

public class FindFiles {
public void find(String dir, String finDir){ 
    try {
        File folder = new File(dir);
        File[] listOfFiles = folder.listFiles();

        ChangeColor change = new ChangeColor();

        for(int i = 0; i < listOfFiles.length; i++) {
            if (listOfFiles[i].isFile()) {
                change.ChangeC(dir, finDir, listOfFiles[i].getName());
            } else if (listOfFiles[i].isDirectory()) {
                File f = new File(finDir+"/"+listOfFiles[i].getName());
                if (!f.isDirectory()) {
                    new File(finDir+"/"+listOfFiles[i].getName()).mkdirs();
                }
                find(dir+"/"+listOfFiles[i].getName(),finDir+"/"+listOfFiles[i].getName());
            }
        }   
    } catch (IOException ex) {
        Logger.getLogger(FindFiles.class.getName()).log(Level.SEVERE, null, ex);
    }
}

}

I would appreciate your help in finding out the reason behind this.

Upvotes: 2

Views: 578

Answers (1)

Brian Topping
Brian Topping

Reputation: 3295

Consider cleaning up your code first, then looking for the error:

public class FindFiles {
    public void find(File src, File target) {
        assert(src.isDirectory() && target.isDirectory());
        try {
            File[] fileList = src.listFiles();

            ChangeColor change = new ChangeColor();

            for (File file : fileList) {
                if (file.isFile()) {
                    change.ChangeC(file, target);
                } else if (file.isDirectory()) {
                    // create the File object for the directory name
                    File newDir = new File(target, file.getName());
                    newDir.mkdir();
                    find(file, newDir);
                }
            }
        } catch (IOException ex) {
            Logger.getLogger(FindFiles.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

You have a lot of unnecessary generation of Files and mixing Strings and Files when a File will do.

You'll need to change the signature of ChangeColor.changeC() to accept the File object that needs to be converted from the source directory and a File object for where it should be written to in the form of the target. The method should make sure the second parameter is a directory as I did here -- never trust a caller!

I haven't tested this code and there's a few other things I'd do differently (like exception handling), but I didn't want the structure to be too different so you could visualize the changes more easily.

What I did here is a form of Defensive Coding. Spend time with Occam's Razor to get the code down to the bare minimum up front. Choose variable names that will make sense when reading the method, not names that look good at the top (and don't be afraid to keep changing them until it reads easily). Bugs that exist will be a lot clearer to find and you will save a lot of time in the long run.

Upvotes: 1

Related Questions