[ACCEPTED]-Java 1.6 - determine symbolic links-java-6

Accepted answer
Score: 49

The technique used in Apache Commons uses 6 the canonical path to the parent directory, not 5 the file itself. I don't think that you 4 can guarantee that a mismatch is due to 3 a symbolic link, but it's a good indication 2 that the file needs special treatment.

This 1 is Apache code (subject to their license), modified for compactness.

public static boolean isSymlink(File file) throws IOException {
  if (file == null)
    throw new NullPointerException("File must not be null");
  File canon;
  if (file.getParent() == null) {
    canon = file;
  } else {
    File canonDir = file.getParentFile().getCanonicalFile();
    canon = new File(canonDir, file.getName());
  return !canon.getCanonicalFile().equals(canon.getAbsoluteFile());
Score: 15

Java 1.6 does not provide such low level 8 access to the file system. Looks like NIO 2, which 7 should be included in Java 1.7, will have 6 support for symbolic links. A draft of the new API is available. Symbolic 5 links are mentioned there, creating and following them is possible. I'm not 4 exactly sure that which method should be 3 used to find out whether a file is a symbolic 2 link. There's a mailing list for discussing NIO 2 - maybe 1 they will know.

Score: 14

Also, watch out for file.isFile() and file.isDirectory() both returning 6 results based on the resolved file and therefore 5 both returning false when file refers to a symlink 4 where the target doesn't exist.

(I know this 3 isn't a useful answer in itself but it tripped 2 me up a couple of times so thought I should 1 share)

Score: 5

It looks like getCanonicalPath() can do other things that 13 might make it different from the absolute 12 path.

This method first converts this pathname 11 to absolute form if necessary, as if by 10 invoking the getAbsolutePath() method, and 9 then maps it to its unique form in a system-dependent 8 way. This typically involves removing redundant 7 names such as "." and ".." from 6 the pathname, resolving symbolic links (on 5 UNIX platforms), and converting drive letters 4 to a standard case (on Microsoft Windows 3 platforms).

But it might work for the vast 2 majority of your use cases; your mileage 1 may vary.

Score: 3

If you are already coding something specifically 3 for *nix, then you could do a shell command 2 from Java like this:

Process p = Runtime.getRuntime().exec(new String[]{"test", "-h", yourFileName});
if (p.exitValue() == 0) 
   System.out.println("This file is a symbolic link");
   System.out.println("This file is not a symbolic link");

That's very specific 1 to *nix, but it does at least work.

Score: 1

Sorry to reply to such an old post, but 7 I was looking for a solution for Windows 6 systems some time back, and some of the 5 previous answers didn't work out for me. If 4 you're not concerned with cross platform 3 compatibility and only need a solution for 2 Windows, the following technique worked 1 well for my purposes.

File f = new File("whatever file or folder");
if (f instanceof ShellFolder) {
  ShellFolder sf = (ShellFolder)f;
  if (sf.isLink()) {
    // Your code when it's a link

More Related questions