簡體   English   中英

Files.walkFileTree 在某些 windows 文件上引發訪問異常

[英]Files.walkFileTree throws access exception on some windows files

我在 Windows 10 Pro 系統上使用Files.walkFileTree() ,並在某些文件上打印異常 stackTrace。 我試圖弄清楚如何確定哪些文件會在拋出這個異常之前拋出它; 到目前為止,我對導致錯誤的文件都不感興趣,但我希望程序能夠在錯誤被拋出之前檢測到哪些文件會拋出錯誤。

代碼:

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)

一些進一步的信息:

  • 在調試器中,文件屬性的 class 是sun.nio.fs.WindowsFileAttributesBasicFileAttributes的擴展。 我不能只導入 WindowsFileAttributes; 它可用於運行時,但我不知道使用什么版本,所以我知道 jar 放在我的構建路徑中。 所以我不能將我的 BasicFileAttributes 變量轉換為 WindowsFileAttributes 並調用它的特定方法,除非我能得到官方保證使用哪個 jar。 我注意到在該 class 的調試器中顯示了一個名為reparseTag的變量,它看起來像一個位掩碼(值為 0x80000001b),但我不知道如何使用它。 對於我查看過的其他幾個文件,該值為 0。

  • 如果我go到DOS命令行,這些文件都在那里; 它們的長度為 0,但磁盤上長度為 0 的其他文件被正確處理。 在 DOS 中,它們也出現在使用dir/al生成的列表中,表明(再次)它們是符號鏈接或重解析點或其他東西。 我相信這是相關的,但想知道我的程序如何檢測到它們不能像其他文件一樣對待。

Path#toRealPath文檔中所述

拋出:
...
SecurityException - 在默認提供程序的情況下,並且安裝了安全管理器,調用其 checkRead 方法來檢查對文件的讀取訪問,並且在此路徑不是絕對路徑的情況下,調用其 checkPropertyAccess 方法來檢查對系統屬性的訪問用戶目錄

因此,要“在拋出錯誤之前檢測哪些文件會拋出錯誤”,只需在調用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;
    }

在訪問文件旁邊的 class 中實現此方法:

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

它處理 SimpleFileVisitor 中的異常。 祝你好運。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM