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)
一些进一步的信息:
在调试器中,文件属性的class是sun.nio.fs.WindowsFileAttributes
,BasicFileAttributes
的扩展。我不能只导入 WindowsFileAttributes;它在运行时可用,但我不知道使用的是什么版本,所以我知道要在我的构建路径中放入什么 jar。所以我不能将我的 BasicFileAttributes 变量转换为 WindowsFileAttributes 并调用它的特定方法,除非我能得到官方保证使用哪个 jar。我注意到在 class 的调试器中显示了一个名为 reparseTag
的变量,它看起来像一个位掩码(值为 0x80000001b),但我不知道如何使用它。我查看过的其他几个文件的值为 0。
如果我进入DOS命令行,这些文件都在那里;它们的长度为 0,但磁盘上其他长度为 0 的文件在处理时没有错误。在 DOS 中,它们也出现在用 dir/al
生成的列表中,表明(再次)它们是符号链接或重新分析点或其他东西。我相信这是相关的,但想知道我的程序如何检测到它们不能像其他文件一样对待。
的文档所述
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 中的异常。
祝你好运。
我在 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)
一些进一步的信息:
在调试器中,文件属性的class是
sun.nio.fs.WindowsFileAttributes
,BasicFileAttributes
的扩展。我不能只导入 WindowsFileAttributes;它在运行时可用,但我不知道使用的是什么版本,所以我知道要在我的构建路径中放入什么 jar。所以我不能将我的 BasicFileAttributes 变量转换为 WindowsFileAttributes 并调用它的特定方法,除非我能得到官方保证使用哪个 jar。我注意到在 class 的调试器中显示了一个名为reparseTag
的变量,它看起来像一个位掩码(值为 0x80000001b),但我不知道如何使用它。我查看过的其他几个文件的值为 0。如果我进入DOS命令行,这些文件都在那里;它们的长度为 0,但磁盘上其他长度为 0 的文件在处理时没有错误。在 DOS 中,它们也出现在用
dir/al
生成的列表中,表明(再次)它们是符号链接或重新分析点或其他东西。我相信这是相关的,但想知道我的程序如何检测到它们不能像其他文件一样对待。
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 中的异常。 祝你好运。