Comp Sci Java Non-Recursive du command popping java.lang.InterruptedException

  • Thread starter Thread starter peterpiper
  • Start date Start date
  • Tags Tags
    Java
AI Thread Summary
The Java program aims to calculate the size of a filesystem object, either a file or a directory, using a non-recursive approach with a stack. Users reported encountering a java.lang.InterruptedException intermittently after the size is reported, suggesting a potential threading issue related to the JFileChooser. Additionally, null pointer exceptions occur when attempting to list files in a directory that may not exist or is not accessible, indicating the need for better error handling. Suggestions include adding checks to ensure that the popped object from the stack is a directory before calling listFiles() and handling potential null returns from this method. Improving these areas may resolve the exceptions encountered during execution.
peterpiper
Messages
12
Reaction score
0

Homework Statement



You are to write a robust program (i.e., a public static void main()) that accepts a file pathname (e.g. 'c:\foo\bar' or '/home/jblow/' under UNIX) as input and then calculates and prints the size of that filesystem object:

java FileSize c:\foo\bar
123625 bytes

The purpose of the program is to compute the total size in bytes occupied by the given object. For files, this is just the size of the file itself. For directories this will be the recursive sum of the sizes of the objects inside the directory.

Homework Equations



N/A

The Attempt at a Solution



Code:
import java.io.File;
import javax.swing.JFileChooser;
import java.util.Stack;
public class FileSize 
{

	/**
	 * FileSize computes the total size of a directory or file.
	 * @param args
	 */
	public static void main(String[] args) 
	{
		//Variable Declaration
		Stack <File> folderStack = new Stack<File>();
		long fileSize = 0;
		JFileChooser chooser = new JFileChooser();
		
		//Only allow the user to select a directory for the time being
		chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
		int returnValue = chooser.showOpenDialog(null);
		
		//If a valid file is selected proceed
    if (returnValue == JFileChooser.APPROVE_OPTION) 
    {
   	//Create a file object from the directory
      File selectedFile = chooser.getSelectedFile();
      //If the file can be read proceed
      if(selectedFile.canRead())
      {
      	if(selectedFile.isDirectory())
      	{
      		//If the file object is a directory, push it on a stack to be operated on later
      		folderStack.push(selectedFile);
      		//Until the stack is empty, keep calculating directory sizes
      		while(!folderStack.isEmpty())
      		{
      			//List directory contents
      			File[] listOfFiles = folderStack.pop().listFiles();
      			for (int i = 0; i < listOfFiles.length; i++)
      			{
      				//If the item is a file, add to total size
      				if(listOfFiles[i].isFile())
      				{
      					fileSize += listOfFiles[i].length();
      					System.out.println(fileSize + " bytes.");
      				}
      				//if it's a directory, push it onto the stack
      				else
      				{
      					folderStack.push(listOfFiles[i]);
      				}
      			}
      		}
      	}
      	//If the selected item is just a file, calculate the size
      	else
      	{
      		fileSize = selectedFile.length();
      	}
      }
      else
      {
      	System.out.println("Borked");
      }
      //Report the size
      long fileSizeKB = fileSize / 1024;
      System.out.println(fileSize + " bytes.");
    }
  }
}

Question [\b]

So overall I have the correct functionality(minus the JFileChooser, but that will change), provided there aren't any protected files in the directory, but I keep getting an odd exception thrown after the final reporting of the file size.
Code:
Exception while removing reference: java.lang.InterruptedException
java.lang.InterruptedException
	at java.lang.Object.wait(Native Method)
	at java.lang.ref.ReferenceQueue.remove(Unknown Source)
	at java.lang.ref.ReferenceQueue.remove(Unknown Source)
	at sun.java2d.Disposer.run(Unknown Source)
	at java.lang.Thread.run(Unknown Source)

An even stranger thing is that it only occasionally does it. I don't change code but it only does it may once out of every 6ish runs? By what I gather it's a threading exception but I don't know why I would be popping that here. Any suggestion for how to drop the error?
 
Physics news on Phys.org
I can't seem to reproduce your error on my Linux box with openjdk, but I do occasionally get a null pointer exception from:

Code:
File[] listOfFiles = folderStack.pop().listFiles();
for (int i = 0; i < listOfFiles.length; i++)

This will happen whenever the File object returned from your folderStack.pop() call is not a directory, or when an I/O error occurs, as both scenarios will assign null to listOfFiles, causing the conditional in your for loop to throw an exception.

This may or may not also be related to your error. I suggest you fix this section of code and try it again several times (with whichever directory was giving you problems before) and see if the issue is still occurring. I suspect that there is a bug in your JDK implementation which is resulting in improper handling of a particular I/O error.
 
By what I gather my error was coming from something wacky with the JFileChooser. On my Windows machines it would pop whenever I chose the default directory brought up by the GUI. As for the null pointers, I just haven't gotten to the point where I was worried about dealing with protected files, which have so far in my experience been the cause of that particular exception. I'm just having trouble tracking down where exactly to check for the nulls.
 
peterpiper said:
As for the null pointers, I just haven't gotten to the point where I was worried about dealing with protected files, which have so far in my experience been the cause of that particular exception. I'm just having trouble tracking down where exactly to check for the nulls.

It isn't just protected files that will cause that error. In your code, you aren't checking whether folderStack.pop() has returned an ordinary file, or a directory (or something else entirely - there are other possibilities for certain architecture & JDK combinations, like drivers for example). If it is an ordinary file (one that you have pushed into your Stack in a previous iteration of the while loop), the subsequent call to listFiles() will return a null object reference (see here). You will need an if statement to ensure that the for loop is only processed when folderStack.pop() is a directory, and that you simply add the size to your total of the file if it is an ordinary file. You will also need an additional if statement to test whether listFiles() returned null due to a file being protected (or any other I/O error) in the case of a directory, prior to executing your for loop.
 

Similar threads

Replies
7
Views
3K
Replies
2
Views
3K
Replies
12
Views
2K
Replies
1
Views
2K
Replies
5
Views
8K
Replies
1
Views
2K
Replies
1
Views
2K
Back
Top