Can Java Files.walk continue executing after encountering an exception error
Asked Answered
H

2

5

This is my first time working with Files.walk in Java, and I rather like it, especially the Path class. It's robust and versatile.

What I'm not liking, however, is that when walking a folder, if the iterator runs into a snag ... like it hits a folder that the user does not have permission to see or whatever error it might encounter, after it throws the exception, it doesn't continue nor does it yield a list of paths to work with.

Here is an example of how I'm using the method:

try {
    Stream<Path> paths    = Files.walk(rootPath);
    List<Path>   pathList = paths.collect(Collectors.toList());
    for (Path path : pathList) {
        //Processing code here
    }
 }
catch (FileSystemException a) {System.err.format("FileSystemException: %s%n", a);System.out.println(a.getStackTrace());}
catch (UncheckedIOException b) {System.err.format("UncheckedIOException: %s%n", b);System.out.println(b.getCause().getLocalizedMessage());}
catch (IOException c) { System.err.format("IOException: %s%n", c);System.out.println(c.getStackTrace());}

Now, if the Files.walk method encounters some kind of error while trying to iterate through the folders, it throws the exception and then of course the code continues after catching the exception.

What I WANT it to do is to ignore any problems it encounters and to just continue to iterate through whatever folders it can without ever stopping.

Is this possible?

Hardcore answered 8/4, 2021 at 2:12 Comment(0)
C
8

You can use Files#walkFileTree() method and implement your own visitor object which will ignore exceptions:

public class Test
{
    public static void main(String[] args) throws Exception
    {
        
        Path rootPath = Path.of("e:\\walkMe");
        Files.walkFileTree(rootPath,new MyVisitor());
    
    }
}
class MyVisitor implements FileVisitor<Path> {

    @Override
    public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
        System.out.println(dir);
        return FileVisitResult.CONTINUE;
    }

    @Override
    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
        System.out.println(file);
        return FileVisitResult.CONTINUE;
    }

    @Override
    public FileVisitResult visitFileFailed(Path file, IOException exc) {
        
        System.out.println("error on: " + file + " " + exc.getClass());
        return FileVisitResult.CONTINUE;
    }

    @Override
    public FileVisitResult postVisitDirectory(Path dir, IOException exc) {    
        return FileVisitResult.CONTINUE;
    }
}

Output:

e:\walkMe
e:\walkMe\ab
e:\walkMe\ab\ab.txt
error on: e:\walkMe\cd class java.nio.file.AccessDeniedException
e:\walkMe\ef
e:\walkMe\ef\ef.txt

Here the application couldn't explore folder cd but it continued walking rest of the folders and files.

Cyrille answered 8/4, 2021 at 2:38 Comment(1)
Thank you for this, I ended up digging deep into how to use the FileVisitor interface and was able to create a stable solution for what I'm doing.Hardcore
C
4

We could still work with Files#walk like this:

Path rootPath = Path.of("e:\\walkMe");
Iterator<Path> itr = Files.walk(rootPath).iterator();
while(true) {
    try {
        if(itr.hasNext()) {
            System.out.println(itr.next());
        } else {
            break;
        }
    }catch(Exception e) {
        System.out.println(e.getLocalizedMessage());
    }
}

Output:

e:\walkMe
e:\walkMe\ab
e:\walkMe\ab\ab.txt
java.nio.file.AccessDeniedException: e:\walkMe\cd
e:\walkMe\ef
e:\walkMe\ef\ef.txt
Cyrille answered 8/4, 2021 at 3:0 Comment(1)
I like this! The treewalk thing seems a bit more robust and feature-rich, but this is good.Hardcore

© 2022 - 2024 — McMap. All rights reserved.