The Java helper class java.nio.file.Files has methods to access file attributes. Some of the class methods follow symbolic links (all methods with a LinkOption parameter), while for some other methods it is not clear wether symbolic links are followed or not (methods without LinkOption parameter).
These are some methods that follow symbolic links:
Files.isDirectory(Path, LinkOption...)Files.isRegular(Path, LinkOption...)Files.getAttribute(Path, String, LinkOption...)Files.getLastModified(Path, LinkOption...)Files.getOwner(Path, LinkOption...)Files.getPosixFilePermission(Path, LinkOption...)
For some other methods, it is no obvious to determine if they follow symbolic links or not (no LinkOption... parameter and no mention of symbolic links in the javadoc) :
Files.isSymbolicLink(Path)Files.isExecutable(Path)Files.isReadable(Path)Files.isWritable(Path)Files.isHidden(Path)Files.size(Path)Files.getFileStore(Path)
Which are the methods without LinkOption... parameter that follow symbolic links, and why ?
TLDR: in most cases this seems to a
FileSystemProviderimplementation choice to follow symbolic links or not (this may answers the "why" question). Symbolic links are:Followed:
Files.size(Path)Mostly followed:
Files.getFileStore(Path): followed on Windows and Linux, not followed on JimfsNot followed:
Files.isSymbolic(Path)Mostly not followed:
Files.isExecutable(Path): not followed on Windows and Unix, but followed on JimfsFiles.isReadable(Path): not followed on Windows and Unix, but followed on JimfsFully implementation specific:
Files.isWritable(Path): followed on Windows but not on UnixFiles.isHidden(Path): followed on Windows but not on UnixYou can be sure about whether symbolic links are followed or not by calling
Files.readAttributes(Path, Class, LinkOption...)and using the returned attributes.Files.isSymbolic(Path)does not follow symbolic linksFor
Files.isSymbolic(Path), the reason is obvious: if the method had followed the symbolic links by default, it would have always returnedfalse.Files.isHidden(Path)follow symbolic links on Windows but not on UnixFrom the method signature, we may think that the method does not follow symbolic links (because there is no
LinkOption...parameter). However, this is not so evident.The
Files.isHidden(Path)method delegate to the implementation of thejava.nio.file.spi.FileSystemProvider.isHidden(Path)and the javadoc does not specify wether the method follows symbolic links or not.On Windows, it is implemented by following symbolic links, see line 465 (the
trueparameter inWindowsFileAttributes.get(file, true)call tells to follow symbolic links):On Unix, this method is implemented without following symbolic links (it only checks that the file starts with a "."):
Thus, we can conclude that this is implementation specific.
Files.isExecutable(Path)don't follow symbolic links in most file-systemsThis method delegate to
Files.isAccessible(Path, AccessMode.EXECUTE), which delegates to theFileSystemProvider.checkAccess(Path, AccessMode...)method.On Windows, the
WindowsFileSystemProvider.checkAccess(Path, AccessMode...)method delegates to thejava.lang.SecurityManagerwhich decides whether the file is executable or not. AFAIK, theSecurityManagerdoes not follow symbolic links, so we can assume thatFiles.isExecutable(Path)does not follow symbolic links on Windows.On Unix, the
UnixFileSystemProvider.checkAccess(Path, AccessMode...)method also delegates to theSecurityManager, we can assume thatFiles.isExecutable(Path)does not follow symbolic links on Unix too.On Jimfs (in-memory file-system from Google), the call delegates to
com.google.common.jimfs.FileSystemView.checkAccess(JimfsPath)which follows symbolic links (even if Jimfs does not support access control):Thus, we can conclude that
Files.isExecutable(Path)may follow symbolic links depending on the file-system, but won't in a majority of the cases (Unix+Windows).Files.isReadable(Path)does not follow symbolic links on most file-systemsThe implementation for
Files.isReadable(Path)is very similar to the one ofisExecutable(Path): don't follow links on Unix and Windows, but follow links on Jimfs.Files.isWritable(Path)As for
Files.isExecutable(Path), theisWritable(Path)method delegates to theFileSystemProvider.checkAccess(Path).On Windows, this requires determining if the file has a read-only attribute, which is done by following links (see
WindowsFileSystemProvidercode above).On Unix, this is apparently done without following symbolic links (see
UnixFileSystemProviderabove).Thus, we can conclude that this is implementation specific.
Files.size(Path)follow symbolic linksThe implementation delegates to
readAttributes, thus it follows symbolic links for all file-system implementations:Files.getFileStore(Path)The method delegates to the
FileSystemProvider.getFileStore(Path)method.On Windows, it uses
WindowsFileStore.create(Path)which follow symbolic links (seetrueparameter):On Unix, the
FileSystemProvider.getFileStore(Path)method is abstract and implemented by subclasses, e.g.[LinuxFileSystem][3]:}
This classes constructs a
UnixFileStoreby getting the attributes with link following (trueparameter inUnixFileAttributes.get()call):In Jimfs, the
FileStoreseems to be attached to the file at creation time, thus, it looks that links are not followed.Thus, we can conclude that
Files.getFileStore(Path)uses symbolic link following in most file-system implementations.