![](/img/trans.png)
[英]Files.walkFileTree throws exception outside visitor methods when walking /proc
[英]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.WindowsFileAttributes
, BasicFileAttributes
的擴展。 我不能只導入 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.