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>
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 >

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?>
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 >

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?
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(); }
}
}
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
>
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
> 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.
@Op. Just a minor thing. Why are you using list() instead of listFiles() ?Kaj
kajbja at 2007-7-13 23:49:27 >

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.
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
>
> 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?