程序的目标是打印我们在客户端指定的文件夹中的所有目录、子目录和文件。这个程序做到了这一点,但在最后,它抛出了一个NullPointerException。我使用递归函数来打印子目录。
错误为
线程中的异常"主";java.lang.NullPointerException在Client.main(Client.java:114(
这是处理列表的客户端程序
try{
File maindir = new File(folder);
if(maindir.exists() && maindir.isDirectory())
{
// array for files and sub-directories
// of directory pointed by maindir
File arr[] = maindir.listFiles();
System.out.println("Files from main directory : " + maindir);
// Calling recursive method
RecursivePrint(arr, 0);
}
}
catch (NullPointerException e) {
System.out.println("NPE caught");
}
这是RecursivePrint
static void RecursivePrint(File[] arr, int level)
{
// for-each loop for main directory files
for (File f : arr)
{
// tabs for internal levels
for (int i = 0; i < level; i++)
System.out.print("t");
if(f.isFile())
System.out.println(f.getName());
else if(f.isDirectory())
{
System.out.println("[" + f.getName() + "]");
// recursion for sub-directories
RecursivePrint(f.listFiles(), level + 1);
}
}
}
有人能帮我弄清楚NullPointerException发生的原因以及如何解决吗?
方法listFiles((作为文档中的状态"如果此抽象路径名不表示目录,或者发生I/O错误,则返回null"因此,当您尝试打印当前用户无法访问的文件夹(例如Windows上的"系统卷信息"(时,您将得到一个数组的null,因此您的catch子句将被捕获。为了防止这种情况,您可以简单地在内部递归调用之前进行检查,如下所示:
// recursion for sub-directories
File[] listFiles = f.listFiles();
if (listFiles != null) {
RecursivePrint(listFiles, level + 1);
}
这将允许您跳过未处理的文件夹并继续打印。
处理此类问题的另一种方法是在内部递归调用周围添加try-catch块,如下所示:
// recursion for sub-directories
File[] arr1 = f.listFiles();
try {
RecursivePrint(arr1, level + 1);
} catch (NullPointerException e) {
// do something
}
您的代码对我来说运行良好,但您的问题可能来自以下行中的f.listFiles()
方法调用:
RecursivePrint(f.listFiles(), level + 1);
查看该方法的java文档,它显示:
返回一个抽象路径名数组,表示由该抽象路径名表示的目录中的文件和目录。如果目录为空,则数组将为空如果此抽象路径名不表示目录,或者发生I/O错误,则返回null。
所以f.listFiles()
有时可能返回null。当你尝试调用它上的任何方法时,这将导致NullPointerException
。
为了防止这种情况,你可以放置一个简单的空检查,如下所示:
File[] files = f.listFiles();
if (files != null) {
RecursivePrint(files, level + 1);
}
所以你的RecursivePrint
方法现在看起来像:
static void RecursivePrint(File[] arr, int level)
{
// for-each loop for main directory files
for (File f : arr)
{
// tabs for internal levels
for (int i = 0; i < level; i++)
System.out.print("t");
if(f.isFile())
System.out.println(f.getName());
else if(f.isDirectory())
{
System.out.println("[" + f.getName() + "]");
// recursion for sub-directories
File[] files = f.listFiles();
if (files != null) {
RecursivePrint(files, level + 1);
}
}
}
}