在基于客户端服务器的程序Java中使用递归函数时发生NullPointerException



程序的目标是打印我们在客户端指定的文件夹中的所有目录、子目录和文件。这个程序做到了这一点,但在最后,它抛出了一个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);
}
}
}
}

最新更新