Files.walkFileTree 对某些 windows 文件抛出访问异常

Files.walkFileTree throws access exception on some windows files

我在 Windows 10 Pro 系统上使用 Files.walkFileTree(),并在某些文件上打印异常 stackTrace。我试图弄清楚如何在抛出异常之前确定哪些文件会抛出该异常;到目前为止 none 引起错误的文件对我来说很有趣,但我希望程序能够在错误被抛出之前检测到哪些文件会抛出错误。

代码:

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;
  }

}

和控制台:

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)

一些进一步的信息:

Path#toRealPath

的文档所述

Throws:
...
SecurityException - In the case of the default provider, and a security manager is installed, its checkRead method is invoked to check read access to the file, and where this path is not absolute, its checkPropertyAccess method is invoked to check access to the system property user.dir

因此,为了“在错误被抛出之前检测出哪些文件会抛出错误”,只需在调用 toRealPath.

之前检查我们是否可以读取文件
    @Override
    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 (!Files.isReadable(p)) {
            say("No right to read");
            return FileVisitResult.CONTINUE;
        }
        if (p.compareTo(p.toRealPath()) != 0) {
            say("not a junction");
        }
        return FileVisitResult.CONTINUE;
    }

在 visitFile 旁边的 class 中实施此方法:

            @Override
            public FileVisitResult visitFileFailed(Path file,
                    IOException exc) {
                System.err.println(exc);
                return FileVisitResult.CONTINUE;
            }

它处理 SimpleFileVisitor 中的异常。 祝你好运。