Rollerball
Rollerball

Reputation: 13108

Working around access denied in a FileWalking Tree in Java7

The following is some simple code just to test the Files.walkFileTree() method. However, the folder /etc/ssl/private, which has these permissions (rwx--x---), throws an exception, even when I thought I guarded it with an if statement (if (permissions.equals("rwx--x---")).

What am I doing wrong? Thanks in advance.

public static void main (String []args) throws IOException, InterruptedException
{       
    Files.walkFileTree(Paths.get("/"), new WalkingTheThing2());
}

@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException
{
    PosixFileAttributeView posixView = Files.getFileAttributeView(dir, PosixFileAttributeView.class);
    PosixFileAttributes posixAttr = posixView.readAttributes();
    String permissions =PosixFilePermissions.toString(posixAttr.permissions());
    if (permissions.equals("rwx--x---"))
    {
        return FileVisitResult.SKIP_SUBTREE;
    }

    return FileVisitResult.CONTINUE;
}

@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
        throws IOException {
    try{

        System.out.println(file.getFileName()+" " +Files.size(file));

        return FileVisitResult.CONTINUE;
    }
    catch(IOException io){return FileVisitResult.CONTINUE;}
}

The exception I get is: java.nio.file.AccessDeniedException: /etc/ssl/private

EDIT: Solved by overriding visitFileFailed:

public FileVisitResult visitFileFailed(Path file, IOException io)
{   
    return FileVisitResult.SKIP_SUBTREE;
}

Upvotes: 17

Views: 4635

Answers (2)

Root
Root

Reputation: 995

If you are traversing the whole directory System and there is a situation where you got some type of Exception like AccessDeniedException and you want skip that file so that you could check the other file you need to override the visitFileFailed and skip that file or directory.

@Override
public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
    System.err.printf("Visiting failed for %s\n", file);
    return FileVisitResult.SKIP_SUBTREE;
} 

This is the work around I have found when Walking through the directory system.

Upvotes: 3

Kunda
Kunda

Reputation: 463

Although overriding visitFileFailed solved your problem, it might be hiding the fact you are still doing several things wrong:

  1. Files.getFileAttributeView can return null (e.g. if the file system does not support POSIX file permissions) making posixView.readAttributes() fail on NPE
  2. posixView.readAttributes() can itself throw exceptions (e.g. if you don't have the required permissions to read the file's permissions) - this might be the cause of the AccessDeniedException you got
  3. Not entirely wrong, but comparing the string representation of the permissions might be inappropriate for this use case, unless you want to explicitly check that the file has the given permissions - and does not have the the others; a different approach would be to check just for the required permissions:

    Set<PosixFilePermission> perm = posixAttr.permissions();
    if (perm.contains(OWNER_READ) || perm.contains(GROUP_READ) || perm.contains(OTHERS_READ)) {
        return FileVisitResult.SKIP_SUBTREE;
    }
    

Upvotes: 0

Related Questions