Reputation: 17443
On Unix, Files.walkFileTree
will callback FileVisitor.visitFile
with BasicFileAttributes
which are actually sun.nio.fs.UnixFileAttributes$UnixAsBasicFileAttributes
. As the debugger shows, the wrapped UnixFileAttributes
already contain permission information (st_mode
field is populated). Is there a (graceful) way to unwrap the UnixFileAttributes$UnixAsBasicFileAttributes
in order to get at least PosixFileAttributes
so the permissions will be accessible? Reflection does not work for me, but results in an IllegalAccessError
when trying to invoke UnixFileAttributes$UnixAsBasicFileAttributes.unwrap
.
Also, I want to avoid to explicitly call Files.getPosixFilePermissions(file)
for every reported file as this gives roughly 10% overhead for my test cases.
Upvotes: 4
Views: 269
Reputation: 9543
In my Java, there's a package-private method just to unwrap the wrapped attributes. No guarantee that any Java will contain this method. For now this works for me and I hope it does for you too.
I can call this method with the following code.
You came very close with your attempt at Java 9: How to retrieve the ctime in FileVisitor.visitFile()?. I simplified it a bit for this question.
try {
Class<?> basicFileAttributesClass = Class.forName("java.nio.file.attribute.BasicFileAttributes");
Class<?> unixFileAttributesClass = Class.forName("sun.nio.fs.UnixFileAttributes");
Method toUnixFileAttributesMethod =
unixFileAttributesClass.getDeclaredMethod("toUnixFileAttributes", basicFileAttributesClass);
toUnixFileAttributesMethod.setAccessible(true);
attrs = (BasicFileAttributes)toUnixFileAttributesMethod.invoke(unixFileAttributesClass, attrs);
} catch (ReflectiveOperationException ex) {
throw new RuntimeException(ex);
}
For Java 9 and up, the setAccessible()
checks module permissions, which your module doesn't have. This can be unlocked with the VM option --add-opens java.base/sun.nio.fs=ALL-UNNAMED
.
Upvotes: 2