Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java non-recursive filesystem walking

Tags:

java

I need to create app which uses non-recursive walk through filesystem and prints out files which are on a certain depth. What I have:

public void putFileToQueue() throws IOException, InterruptedException {
File root = new File(rootPath).getAbsoluteFile();
checkFile(root, depth);
    Queue<DepthControl> queue = new ArrayDeque<DepthControl>();
    DepthControl e = new DepthControl(0, root);
    do {
        root = e.getFileName();

        if (root.isDirectory()) {
            File[] files = root.listFiles();

            if (files != null)
                for (File file : files) {

                    if (e.getDepth() + 1 <= depth && file.isDirectory()) {
                        queue.offer(new DepthControl(e.getDepth() + 1,file));
                    }

                    if (file.getName().contains(mask)) {
                        if (e.getDepth() == depth) {
                            System.out.println(Thread.currentThread().getName()
                                    + " putting in queue: "
                                    + file.getAbsolutePath());
                        }
                    }
                }
                } 
        e = queue.poll();
    } while (e != null);
}

And helper class

public class DepthControl {

    private int depth;
    private File file;

    public DepthControl(int depth, File file) {

        this.depth = depth;
        this.file = file;
    }

    public File getFileName() {
        return file;
    }

    public int getDepth() {
        return depth;
    }
}

I received answer, that this program uses additional memory because of Breadth-first search(hope right translation). I have O(k^n), where k - average amount of subdirectories, n - depth. This program could be easily done with O(k*n). Please help me to fix my algorithm.

like image 435
user1255246 Avatar asked May 14 '26 23:05

user1255246


1 Answers

I think this should do the job and is a bit simpler. It just keeps track of files at next level, expands them, then repeats the process. The algorithm itself keeps track of depth so there is no need for that extra class.

// start in home directory.
File root = new File(System.getProperty("user.dir"));

List<File> expand = new LinkedList<File>();
expand.add(root);

for (int depth = 0; depth < 10; depth++) {
    File[] expandCopy = expand.toArray(new File[expand.size()]);
    expand.clear();
    for (File file : expandCopy) {
        System.out.println(depth + " " + file);
        if (file.isDirectory()) {
            expand.addAll(Arrays.asList(file.listFiles()));
        }
    }
}
like image 158
Adam Avatar answered May 17 '26 13:05

Adam



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!