Recursion - NullPointer Exception

Hi -

I am in the process of writing a program that will output a file that contains a list of all database's (.mdb) in a particular Directory (including Subdirectories)

The directory I want to search though is approaching 1 Terabyte in size, and it has numerous subdirectories (as you can imagine)

The code I have written will work in a smaller directory, however when i try to run it for the directory i want (the 1 TB Directory) i get a Null Pointer Exception.

The code is written based on recursion, if a file within the main directory is a folder, it will call the function again using the new folder as the directory and so on.

I've included the function below:

extension is a class variable, a string that contains ".mdb"

//*****************Code Start********************************

public static void FileNames(File dir){

try{

FileWriter fw = new FileWriter("C:\\Database Listing.txt");

if(dir.isDirectory()){

String[] children = dir.list();

String filename;

for(int i=0;i<children.length;i++){

filename = children;

File dirChild = new File(dir, children);

if(dirChild.isDirectory()){

FileNames(dirChild);

}else{

if(filename.endsWith(extension)){

fw.write(dir + "\\" + filename + System.getProperty("line.separator"));

}

}

}

fw.close();

}

}catch(IOException e){

System.out.println("Exception 1: "+ e.toString());

}

}

//*******************Code End******************************

Is there anyway around this problem (if recursion is the problem, which i assume it is as the code works fine on a smaller directory)

Thanks in advance,

Gavin>

[1779 byte] By [gavinclarkea] at [2007-10-2 21:04:17]
# 1
Hi,The recursion is probably not the problem, sice that wouldn't give a null pointer exception. What does the stacktrace say?Kaj
kajbja at 2007-7-13 23:49:27 > top of Java-index,Java Essentials,New To Java...
# 2

Hi -

java.lang.NullPointerException

at FileFinder.FileNames(FileFinder.java:60)

at FileFinder.FileNames(FileFinder.java:64)

at FileFinder.FileNames(FileFinder.java:64)

at FileFinder.main(FileFinder.java:41)

Line 60 is the For loop:

for(int i=0;i<children.length;i++)

what would cause this to throw the null pointer? even if there are no files in a directory, this still shouldn't happen?>

gavinclarkea at 2007-7-13 23:49:27 > top of Java-index,Java Essentials,New To Java...
# 3
It's hard to read your code since you didn't use code tags when you posted.The line throws an exception if children is null.Kaj
kajbja at 2007-7-13 23:49:27 > top of Java-index,Java Essentials,New To Java...
# 4
dir.list(); may return null if dir isn't a directory (not the case) or if there is some io problems, may be ther are access problems in your case?
s-e-r-g-ea at 2007-7-13 23:49:27 > top of Java-index,Java Essentials,New To Java...
# 5

hi there,

give this a try.

import java.io.*;

import java.util.*;

public class ti

{

public static void main(String[] args)

{

File rootDir = new File(args[0]);

HashMap map = new HashMap();

listMdbs(rootDir, map);

writeToFile("test.txt", map.keySet());

//System.out.println(map.keySet());

}

private static void listMdbs(File rootDir, HashMap map) {

if(rootDir.isDirectory()) {

File[] fileList = rootDir.listFiles();

if(fileList != null ) {

for(int i=0; i < fileList.length; i++) {

if( !fileList[i].isDirectory() && fileList[i].getName().endsWith(".mdb"))

map.put(fileList[i].getAbsolutePath(), fileList[i].getName());

else

listMdbs(fileList[i], map);

}

}

}

}

private static void writeToFile(String filename, Set filePaths){

try {

PrintWriter bw = new PrintWriter(new BufferedWriter(new FileWriter(filename)));

for(Iterator i = filePaths.iterator(); i.hasNext(); ) {

bw.println(i.next());

}

bw.close();

}catch(Exception e){e.printStackTrace(); }

}

}

SPeravalia at 2007-7-13 23:49:27 > top of Java-index,Java Essentials,New To Java...
# 6

I've attached the code again with tags, sorry about that.

firstly, i assume that dir.list() can't return null as it is surrounded with the if block - if(dir.isDirectory()){...}

as for access problems, im not sure what you mean? I have full read write access to the entire drive, the only thing then that i can think of is if a particular file is read only? or something like that? i don't know that this would affect it though?

I've made some changes to the code to try and avoid access errors, i.e. here's the entire code. I've moved the FileWriter to the main class so it won't close until the job is complete etc.

import java.io.*;

public class FileFinder {

private static String extension;

private String FilePath;

private static FileWriter fw;// = new FileWriter("C:\\Database Listing.txt");

/** Creates a new instance of FileFinder */

public FileFinder() {

}

/** Creates a new instance of FileFinder with user defined extension */

public FileFinder(String extension) {

this.extension = extension;

}

/**

* @param args the command line arguments

*/

public static void main(String[] args) {

// TODO code application logic here

extension = ".mdb";

File dir = new File("C:\\");

try{

fw = new FileWriter("C:\\Database Listing.txt");

FileNames(dir);

fw.close();

}catch(NullPointerException np){

//System.out.println("Null Pointer: " + np.toString());

// System.out.println("Null Pointer 2: " + np.getStackTrace());

np.printStackTrace();

}catch(IOException exc){

exc.printStackTrace();

}

}//main

public static void FileNames(File dir){

try{

//FileWriter fw = new FileWriter("C:\\Database Listing.txt");

if(dir.isDirectory()){

String[] children = dir.list();

String filename;

for(int i=0;i<children.length;i++){

filename = children[i];

File dirChild = new File(dir, children[i] + "\\");

if(dirChild.isDirectory()){

FileNames(dirChild);

}else{

if(filename.endsWith(extension)){

fw.write(dir + "\\" + filename + System.getProperty("line.separator"));

}

}

}

}

}catch(IOException e){

System.out.println("Exception 1: "+ e.toString());

}

}

}//class

>

gavinclarkea at 2007-7-13 23:49:27 > top of Java-index,Java Essentials,New To Java...
# 7

May i suggest one change.

> public static void FileNames(File dir){

>

> try{

> FileWriter fw = new

> FileWriter("C:\\Database Listing.txt");

Shouldnt this *filewriter* be declared as static and placed and initialized outside the function.

I've been running your code on my system for the past 30 mins continously to list all exe on my system. Its still running but i guess you should also put *fw.flush()* immediately after fw.write() so that data gets immediately written on the file.

Regards

Neeraj.Malhotraa at 2007-7-13 23:49:27 > top of Java-index,Java Essentials,New To Java...
# 8

> May i suggest one change.

>

> > public static void FileNames(File dir){

> >

> > try{

> > FileWriter fw = new

> > FileWriter("C:\\Database Listing.txt");

>

> Shouldnt this *filewriter* be declared as static and

> placed and initialized outside the function.

>

Sorry about this. I was looking at your first post.

Neeraj.Malhotraa at 2007-7-13 23:49:27 > top of Java-index,Java Essentials,New To Java...
# 9
@Op. Just a minor thing. Why are you using list() instead of listFiles() ?Kaj
kajbja at 2007-7-13 23:49:27 > top of Java-index,Java Essentials,New To Java...
# 10

My suggestion is to put a System.out.println("dir: "+dir+"\tlist: "+dir.list()); or something like that before the for loop that gives the null pointer. One thing this will do is validate the assumption that dir.list() is returning null. It will also provide the directory in which this is happening. If it always happens on a specific directory or a directory with certain attributes, it may lead to identifying the problem.

atmguya at 2007-7-13 23:49:27 > top of Java-index,Java Essentials,New To Java...
# 11

I seem to have gotten it working, thanks for all you help - I've tested it on my C drive and it worked, and I am now running it on the large 1TB directory and it seems ok (txt file up to 26Kb with approx 400 databases found so far)

The only thing that I changed in the second piece of code was that I checked to see if(children != null) before i entered the for loop,

as per the code posted by SPeravali

It could probably be more efficient but that's work for another day!!

Again thanks for all your help, and the working code is below:

/**

* FileFinder.java

*

* Created on May 25, 2006, 3:45 PM

*

* To change this template, choose Tools | Template Manager

* and open the template in the editor.

*/

/**

*

* @author clarkeg

*/

import java.io.*;

import javax.swing.*;

public class FileFinder {

private static String extension;

private String FilePath;

private static FileWriter fw;

/** Creates a new instance of FileFinder */

public FileFinder() {

}

/** Creates a new instance of FileFinder with user defined extension */

public FileFinder(String extension) {

this.extension = extension;

}

/**

* @param args the command line arguments

*/

public static void main(String[] args) {

// TODO code application logic here

extension = ".mdb";

File dir = new File("M:\\");

try{

fw = new FileWriter("C:\\Database Listing.txt");

FileNames(dir);

fw.close();

JOptionPane.showMessageDialog(null, "List of Database's has been written to C:\\Database Listing.txt", "Database Listing", JOptionPane.INFORMATION_MESSAGE);

}catch(NullPointerException np){

//System.out.println("Null Pointer: " + np.toString());

// System.out.println("Null Pointer 2: " + np.getStackTrace());

np.printStackTrace();

}catch(IOException exc){

exc.printStackTrace();

}

}//main

public static void FileNames(File dir){

try{

//FileWriter fw = new FileWriter("C:\\Database Listing.txt");

if(dir.isDirectory()){

String[] children = dir.list();

String filename;

if(children != null){

for(int i=0;i<children.length;i++){

filename = children[i];

File dirChild = new File(dir, children[i] + "\\");

if(dirChild.isDirectory()){

FileNames(dirChild);

}else{

if(filename.endsWith(extension)){

fw.write(dir + "\\" + filename + System.getProperty("line.separator"));

fw.flush();

}

}

}

}

}

}catch(IOException e){

System.out.println("Exception 1: "+ e.toString());

}

}

}//class

>

gavinclarkea at 2007-7-13 23:49:27 > top of Java-index,Java Essentials,New To Java...
# 12

> I've been running your code on my system for the past

> 30 mins continously to list all exe on my system. Its

> still running but i guess you should also put

> *fw.flush()* immediately after fw.write() so that

> data gets immediately written on the file.

>

Got that NullPointerException on my system. After writing more than 24000 entries it gave NullPointerException. I feel this problem may have come because of SymLink Driver being installed on my system. Do u also have such kind of driver installed on your test bed?

Neeraj.Malhotraa at 2007-7-13 23:49:27 > top of Java-index,Java Essentials,New To Java...