Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cross platform way to detect a symbolic link / junction point?

In java, a symbolic link in a Unix environment can be detected by comparing the file's canonical and absolute path. However, this trick does not work on windows. If I execute

mkdir c:\foo
mklink /j c:\bar

from the command line and then execute the following lines in java

File f = new File("C:/bar");
System.out.println(f.getAbsolutePath());
System.out.println(f.getCanonicalPath());

the output is

C:\bar
C:\bar

Is there any pre-Java 7 way of detecting a junction in windows?

like image 793
Jherico Avatar asked Jul 14 '10 18:07

Jherico


2 Answers

There doesn't appear to be any cross platform mechanism for this in Java 6 or earlier, though its a fairly simple task using JNA

interface Kernel32 extends Library {
  public int GetFileAttributesW(WString fileName);
}

static Kernel32 lib = null;
public static int getWin32FileAttributes(File f) throws IOException { 
  if (lib == null) {
    synchronized (Kernel32.class) {
      lib = (Kernel32) Native.loadLibrary("kernel32", Kernel32.class);
    }
  }
  return lib.GetFileAttributesW(new WString(f.getCanonicalPath()));
}

public static boolean isJunctionOrSymlink(File f) throws IOException {
  if (!f.exists()) { return false; }
  int attributes = getWin32FileAttributes(f);
  if (-1 == attributes) { return false; }
  return ((0x400 & attributes) != 0);
}

EDIT: updated per comment about possible error return by getWin32FileAttributes()

like image 83
Jherico Avatar answered Oct 11 '22 08:10

Jherico


The answer is 'no'. Junction points and symbolic links are not the same sort of thing. The JRE doesn't check for them, and so the functions you cite don't differentiate them.

Having said this, you might accomplish something with the following:

If the junctioned directory has contents, then the result of getting the canonical pathname of something down below it might be 'surprising' and reveal the situation, since it is likely to be a pathname under the target of the junction. This only works if the directory pointed to by the junction is, of course, non-empty.

like image 45
bmargulies Avatar answered Oct 11 '22 09:10

bmargulies