今天我编写了一个小型Java程序来查找硬盘上的文件,部分原因是Windows缺少合适的文件,部分原因是因为它很有趣。它只是遍历目录的所有子节点,并且如果它们是目录,则递归遍历所有子节点。但后来我有一个NullPointerException
。经过一些System.out.println()'s
和try-catch block
我发现这种情况发生在D:\System Volume Information
,C:\Users\Public\Documents\My Videos
和C:\ProgramData\Templates
等目录上。 Windows本身说,当在资源管理器地址栏中输入"访问被拒绝"。当探索时,它们似乎被锁定了。来自java.io.File
的{{3}}告诉我:
public File[] listFiles() {
String[] ss = list();
if (ss == null) return null; //This line seems to cause the NPE
int n = ss.length;
File[] fs = new File[n];
for (int i = 0; i < n; i++) {
fs[i] = new File(ss[i], this);
}
return fs;
}
我的问题是,为什么没有正确的发言权,IOException
,SecurityException
,甚至是IDontCareWhatKindOfExceptionButPleaseNoNullPointerExceptionException
?
我知道我try-catch
只能NPEs
,或检查null
,但我真的很好奇为什么没有Exception
try/catch
抛出。
由于代码的审美价值,我不喜欢null
并检查try/catch
,因此我制作了一些讨厌的,令人讨厌的反射代码(有许多虚伪的java.io.File
块),它模仿了一些来自java.io.FileSystem
的方法,因为它们是私有的,而某些包(例如array
)不可见。因为我不关心某些Windows文件,我只是使用这段代码忽略它们,给我一个空的public static File[] listFiles(File mThis) {
String[] ss = list(mThis);
if (ss == null) {
//System.out.println("ss is null");
return new File[] {};
}
int n = ss.length;
File[] fs = new File[n];
for (int i = 0; i < n; i++) {
fs[i] = getNewFile(ss[i], mThis);
}
return fs;
}
:
try/catch
编辑:为了避免误解:我做使用{{1}},我只是不美观。
EDIT2:我宁愿使用GUI而不是命令提示符。而且我非常不喜欢Windows Search GUI。使用它几乎是痛苦的。
答案 0 :(得分:3)
简短回答:
Files
API。之后你永远不会回到File
。
答案 1 :(得分:2)
之所以如此,是因为API的设计者在函数合同(文档+签名)中正确识别了原因:
如果此抽象路径名不表示目录,那么这个 方法返回null。否则返回一个File对象数组, 一个用于目录中的每个文件或目录。路径名表示 目录本身和目录的父目录不是 包括在结果中。每个生成的抽象路径名都是 使用File(File,String)从这个抽象路径名构造 构造函数。因此,如果此路径名是绝对的,那么每个 结果路径名是绝对的;如果这个路径名是相对的,那么每个 结果路径名将相对于同一目录。
它返回null并给出具体原因。
因为我不喜欢try / catch并检查null 代码的审美价值
它可能是API的“短缺”,但你公然无视它,因此你的程序崩溃了。