Using Java.io.file, subdirectories can be found using one way but not another

38 Views Asked by At

In my school assignment, we are tasked with using threads to speed up a file searching algorithm. The original program they gave us was this:

package filefinder;

import java.io.File;
import java.io.IOException;

public class FileFinder {
    private final File rootDir;

    public FileFinder(String root) throws IOException {
        rootDir = new File(root);
        if (!(rootDir.exists() && rootDir.isDirectory())) {
            throw new IOException(root + " is not a directory");
        }
    }

    public void findFile(String file) {
        find(rootDir, file);
    }

    private void find(File rootDir, String fileName) {
        File[] files = rootDir.listFiles();
        if (files != null) {
            for (File file : files) {
                if (file.getName().equals(fileName)) {
                    System.out.println("Found at: " + file.getAbsolutePath());
                } else if (file.isDirectory()) {
                    find(file, fileName);
                }
            }
        }
    }
}

Which is called in the main file:

package filefinder;

import java.io.IOException;

public class Main {

    public static void main(String[] args) {
        try {
            String goal = "needle.txt";
            String root = "haystack";
            FileFinder ff = new FileFinder(root);
            ff.findFile(goal);
            
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

This finds the file. Then, to run it with threads, I tried to split it into 5 threads, 1 for each of the 5 subdirectories.

package filefinder;

import java.io.IOException;
import java.io.File;

public class Main {

    public static void main(String[] args) {
        try {
            String goal = "needle.txt";
            String root = "haystack";
            File file = new File(root);
            File[] children = file.listFiles();
            System.out.println(children);
            for (File child : children)
            {
                if (child.isDirectory()){
                    new FileFinder(child.getName());}
            }
            
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Yet now, it throws the exception "haystack1 is not a directory". Why is it not able to find the subdirectories this way? Thank you.

I did managed to run it with threads, but it didn't improve performances at all. A classmate of mine said it was because I defined a new thread during each iteration of the for-loop, which is why here I'm trying to just create a new thread for each of the direct subdirectories, so the 5 folders inside of the main folder.

The folder we're searching through is called 'haystack', containing 5 folders called 'heystack1' to 'heystack5', each with the same 5 folders until a certain point.

1

There are 1 best solutions below

2
On

This is because you're passing only the file name, to FileFinder.

Which, is technically just the last element within the path.

You'll need to pass the entire path.

You can use File#getPath for the relative path, and File#getAbsolutePath for the absolute path.
Similarly, you can use File#getAbsoluteFile to return the value as a File object.

new FileFinder(child.getAbsolutePath());
new FileFinder(child.getPath());