I am using Files.walkFileTree() on a Windows 10 Pro system, and prints an exception stackTrace on some files. I'm trying to figure out how to determine what files will throw this exception before it is thrown; so far none of the files that cause the error are interesting to me, but I want the program to be able to detect which files would throw the error before it's thrown.
code:
import java.io.File;
import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
public class WindowsFilePlay extends SimpleFileVisitor<Path>
{
public static void say(String s) { System.out.println(s); }
public static void main(String[] args) throws IOException
{
WindowsFilePlay play = new WindowsFilePlay();
play.go();
}
private void go() throws IOException
{
say("For running on a Windows system.");
String dirString = "c:\\users\\ralph\\appdata\\local\\microsoft\\windowsapps\\";
File dirFile = new File(dirString);
Path dirPath = dirFile.toPath();
Files.walkFileTree(dirPath, this);
say("done.");
}
public FileVisitResult visitFile(Path p, BasicFileAttributes bfa) throws IOException
{
say("visiting " + p.toString());
if (bfa.isSymbolicLink()) { say("It's a link"); } else { say("It's not a link"); }
if (p.compareTo(p.toRealPath()) != 0) { say("not a junction"); }
return FileVisitResult.CONTINUE;
}
}
and console:
visiting c:\users\ralph\appdata\local\microsoft\windowsapps\GameBarElevatedFT_Alias.exe
It's not a link
Exception in thread "main" java.nio.file.FileSystemException: c:\users\ralph\appdata\local\microsoft\windowsapps\GameBarElevatedFT_Alias.exe: The file cannot be accessed by the system.
at sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:86)
at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:97)
at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:102)
at sun.nio.fs.WindowsLinkSupport.getFinalPath(WindowsLinkSupport.java:74)
at sun.nio.fs.WindowsLinkSupport.getRealPath(WindowsLinkSupport.java:242)
at sun.nio.fs.WindowsPath.toRealPath(WindowsPath.java:836)
at sun.nio.fs.WindowsPath$WindowsPathWithAttributes.toRealPath(WindowsPath.java:138)
at WindowsFilePlay.visitFile(WindowsFilePlay.java:32)
at WindowsFilePlay.visitFile(WindowsFilePlay.java:1)
at java.nio.file.Files.walkFileTree(Files.java:2670)
at java.nio.file.Files.walkFileTree(Files.java:2742)
at WindowsFilePlay.go(WindowsFilePlay.java:24)
at WindowsFilePlay.main(WindowsFilePlay.java:15)
Some further information:
In the debugger, the class for the file attributes is
sun.nio.fs.WindowsFileAttributes, an extension ofBasicFileAttributes. I cannot just import WindowsFileAttributes; it's available to the runtime, but I don't know what version is used so I know what jar to put in my buildpath. So I cannot cast my BasicFileAttributes variable to WindowsFileAttributes and call its specific methods, unless I can get official assurance of which jar to use. I've noticed that there is a variable shown in the debugger for that class calledreparseTag, which looks like a bit mask (value of 0x80000001b), but I don't know how to use it. The value is 0 for the few other files for which I've looked at it.If I go to the DOS command line, these files are all there; they have 0 length, but other files on the disk with 0 length are processed without error. In DOS, they also appear in a list produced with
dir/al, indicating (again) that they are symbolic links or reparse points or something. I'm confident this is related, but want to know how my program can detect that they cannot be treated like other files.