0

The program's objective is to print all the directories, sub-directories and files from the folder that we specify on the Client side. This program does that, but in the very end, it throws a NullPointerException. I use a recursive function to print the sub-dirs.

The error is

Exception in thread "main" java.lang.NullPointerException at Client.main(Client.java:114)

Here is the Client-side program which deals with the listing

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");
}

Here is 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); 
             } 
         } 
    }

Can someone help me figure out why the NullPointerException occurs and how to resolve it?

Purvi
  • 1
  • Working with List interface is safer and you can convert your array of File[] to list by using this: List fileList = Arrays.asList($yourArrayHere$); – Ganesh Giri Sep 29 '20 at 04:50
  • @GaneshGiri List doesn't seem to have methods like getName, isDirectory which are required for this program – Purvi Sep 29 '20 at 05:49

2 Answers2

0

The method listFiles() as states in docs "Returns null if this abstract pathname does not denote a directory, or if an I/O error occurs." So when you try to print a folder that can't be accessed by current user (such as "System Volume Information" on Windows) you will get a null insted of an array, so your catch clause will be caught. To prevent that you can simply put a check before your internal recursive call like that:

            // recursion for sub-directories

            File[] listFiles = f.listFiles();
            if (listFiles != null) {
                RecursivePrint(listFiles, level + 1);
            }

This will allow you to skip unaccessed folder and proceed with printing.

The other method for dealing with such a problem is to add try-catch block around you internal recursive call like that:

            // recursion for sub-directories

            File[] arr1 = f.listFiles();
            try {
                RecursivePrint(arr1, level + 1);
            } catch (NullPointerException e) {
                // do something
            }
admi
  • 91
  • 1
  • 1
  • 8
0

Your code ran fine for me, but your issue is likely coming from the f.listFiles() method call in the line:

RecursivePrint(f.listFiles(), level + 1); 

Looking at the java docs for that method it reads:

Returns An array of abstract pathnames denoting the files and directories in the directory denoted by this abstract pathname. The array will be empty if the directory is empty. Returns null if this abstract pathname does not denote a directory, or if an I/O error occurs.

So it seems like f.listFiles() might sometimes return null. Which will cause a NullPointerException when you try and call any methods on it.

To protect against this you can put a simple null check in place like so:

File[] files = f.listFiles();
if (files != null) {
    RecursivePrint(files, level + 1);
}

So your RecursivePrint method would now look like:

    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);
                }
            }
        }
    }
Dharman
  • 30,962
  • 25
  • 85
  • 135