Reputation: 13153
I thought I had read that if the absolute and canonical paths of a given file did not match, that that meant the file was a symbolic link.
I'm on Windows 10, and it has things it calls "Junctions"; the above test finds identical strings for those two items. I also have found no other way to distinguish these files, having tried the calls below:
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes;
public class WindowsFilePlay2
{
public static void main(String[] args)
{
WindowsFilePlay2 play2 = new WindowsFilePlay2();
play2.go();
}
private void go()
{
File[] fileList = { new File("c:\\Users\\Ralph\\AppData\\Local\\")
,new File("c:\\Users\\Ralph\\AppData\\")
,new File("c:\\users\\ralph\\")
};
try
{
for (File file : fileList)
{
Path filePath = file.toPath();
String absolute = file.getAbsolutePath();
String canonical = file.getCanonicalPath();
String realPath = filePath.toRealPath().toString();
boolean answer = Files.isSymbolicLink(filePath);
boolean isFile = file.isFile();
boolean isAbsolute = file.isAbsolute();
boolean isDirectory = file.isDirectory();
boolean isHidden = file.isHidden();
boolean isReadable = Files.isReadable(filePath);
BasicFileAttributes attributes = Files.readAttributes(filePath, BasicFileAttributes.class);
boolean isLink = attributes.isSymbolicLink();
boolean isOther = attributes.isOther();
absolute = absolute.toLowerCase();
canonical = canonical.toLowerCase();
System.out.printf("filePath %s%n"
+ "absolute %s%n"
+ "canonical %s%n"
+ "realPath %s%n"
+ "answer %b%n"
+ "isFile %b%n"
+ "isAbsolute %b%n"
+ "isDirectory %b%n"
+ "isHidden %b%n"
+ "isLink %b%n"
+ "isOther %b%n"
+ "isReadable %b%n"
+ "%n"
, filePath.toString(), absolute, canonical, realPath, answer, isFile, isAbsolute, isDirectory, isHidden, isLink, isOther, isReadable
);
}
}
catch (IOException ioe)
{
ioe.printStackTrace();
}
}
}
The output from this:
filePath c:\Users\Ralph\AppData\Local
absolute c:\users\ralph\appdata\local
canonical c:\users\ralph\appdata\local
realPath C:\Users\ralph\AppData\Local
answer false
isFile false
isAbsolute true
isDirectory true
isHidden false
isLink false
isOther false
isReadable true
filePath c:\Users\Ralph\AppData
absolute c:\users\ralph\appdata
canonical c:\users\ralph\appdata
realPath C:\Users\ralph\AppData
answer false
isFile false
isAbsolute true
isDirectory true
isHidden true
isLink false
isOther false
isReadable true
filePath c:\users\ralph
absolute c:\users\ralph
canonical c:\users\ralph
realPath C:\Users\ralph
answer false
isFile false
isAbsolute true
isDirectory true
isHidden false
isLink false
isOther false
isReadable true
But AppData
and AppData\Local
are not real files; they're junctions or links or whatever to other files. I don't know what they would be called in the Java API. My program wants to avoid them, since it is going through the actual directories on the disk and does not want to visit any directory subtrees twice. So how can I determine that I have one of these, whatever they're called?
Upvotes: 3
Views: 668
Reputation: 13153
User error -- OP here, I was using the translation of the Junctions instead of the junctions themselves, e.g., c:\users\ralph\Application Data\
is what I should be testing -- that's the junction -- and it translates to c:\users\ralph\AppData\Roaming
. But I was testing the latter, expecting to find some way of finding out it was a link or something, but it is not. When I test with the actual Windows Junction, the realPath
value from the output above is different than the filePath
value.
Thanks to those who responded.
Upvotes: 2