-1
//Author: Darin Park
//Date: 24 October, 2014
//Version: 2
package readandcopyupdate1;

import java.util.ArrayList;
import java.io.*;

public class ReadAndCopyUpdate1{

public static void main(String[] args){
    ReadAndCopyUpdate1 rc = new ReadAndCopyUpdate1();
    final File folder1 = new File("/root/avatar/default/upload/member");
    final File folder2 = new File("/root/avatar/default/upload/Transfer");
    rc.listFilesForOldFolder(folder1,rc.oldFiles);
    rc.listFilesForNewFolder(folder2,rc.newFiles);
            rc.oldFiles.stream().forEach((oldFile) -> {
                System.out.println(oldFile);
        });

    System.out.println("\n\n");
            rc.newFiles.stream().forEach((newFile) -> {
                System.out.println(newFile);
        });


}

private void listFilesForOldFolder(final File folder, ArrayList arrayList) {
   /* 
    * This method takes two arguments. 
    * The first argument is the Original Avatar Upload Folder which we want to scan.
    * The second argument is the ArrayList where we want to store all the avatar file names.
    * The first argument is not a string, it's a File.
    * So we need to first convert string to a File by using File Method. Look below for example.
    * final File folder1 = new File("/root/avatar/default/upload/member");
   */
    for (final File fileEntry : folder.listFiles()) {
        if (fileEntry.isDirectory()) {
            listFilesForOldFolder(fileEntry, arrayList);
        } else {
            String str = fileEntry.getName(); 
            if(str.equals("index.html")){
              continue;
            }          
            if(str.charAt(32) == '9'){
                arrayList.add(str);
            }
        }
    }
}

private void listFilesForNewFolder(final File folder, ArrayList arrayList) {
    /*
     * This method takes two arguments.
     * The first argument is the New Transfer folder where we want to store avatar's copy.
     * The second argument is the ArrayList where we want to store all the avatar names in the new Transfer folder.
     * The first argument is not a string, it's a File.
     * So we need to first convert string to a file by using File method. Look below for example.
     * final File folder2 = new File("/root/avatar/default/upload/Transfer");
    */  
    for (final File fileEntry : folder.listFiles()) {
        if (fileEntry.isDirectory()) {
            listFilesForNewFolder(fileEntry, arrayList);
        } else {
            String str = fileEntry.getName();          
            arrayList.add(str);
        }
    }
}



private final ArrayList<String> oldFiles = new ArrayList<>(5);
private final ArrayList<String> newFiles = new ArrayList<>(5);

}

These method used to work in my first version without any problem and now they are suddenly throwing null pointer exception when I am rewriting the code and was doing unit testing for these methods.

Exception in thread "main" java.lang.NullPointerException
    at readandcopyupdate1.ReadAndCopyUpdate1.listFilesForOldFolder(ReadAndCopyUpdate1.java:33)
at readandcopyupdate1.ReadAndCopyUpdate1.main(ReadAndCopyUpdate1.java:15)

What I am trying to accomplish is the following: 1. folder1 consist of files which have 33 characters in their file name. I want to pick all those files which have number 9 in their 33th position.

  1. I'll store all such file names in an arrayList 'oldFiles'
  2. I'll scan folder2 and store all files there in arrayList 'newFiles'
    1. I am testing them by printing arrayLists values on sceen.
  • 1
    Avoid code like this if(str.equals("index.html")){, write if("index.html".eauals(str)){ instead. This will be NPE safe. – Beri Oct 24 '14 at 07:38
  • So, which line is line 33? What could possibly be null at this line? What happens when inspecting the variables used at this line using your debugger? – JB Nizet Oct 24 '14 at 07:41
  • http://stackoverflow.com/questions/218384/what-is-a-null-pointer-exception-and-how-do-i-fix-it/24100776#24100776 – assylias Oct 24 '14 at 07:44
  • @Beri In principle you are right, but in this case it won't help because he uses `str.charAt()` two lines later, and you can't save this one with this trick – Absurd-Mind Oct 24 '14 at 07:44
  • @Beri or not - if you expect str to be non null, what you suggest may hide or delay bugs... – assylias Oct 24 '14 at 07:45
  • General null should be checked first, and this is first type of test that should be written to coverage that. But form my experience this notation is better:) Saved my life in few places. – Beri Oct 24 '14 at 07:47
  • I don't see how a file could have a null name. That is probably not the reason of the exception. Now if only the OP would tell us which is line 33... Hint to the OP: read the javadoc of `listFiles()`, until the end. – JB Nizet Oct 24 '14 at 07:50
  • Please take a look at [javadoc](http://docs.oracle.com/javase/7/docs/technotes/guides/javadoc/) for documenting your methods, classes ... – yunandtidus Oct 24 '14 at 08:43

3 Answers3

1

Here, the caveats are:

Line: "for (final File fileEntry : folder.listFiles())"

This line may return null, if the folder path does not exist. So check for null for fileEntry variable before processing it.

Line: "String str = fileEntry.getName();"

Check for null/empty for this str variable, before checking it with other values.

  • folder path exist and I am sure about it. There are two reason why I am so sure. 1) My version 1 of this program is using the same folder. I have copied and pasted the same path here. 2). I can cd into that directory by using my terminal. – user3774654 Oct 24 '14 at 08:08
0

Do a test that str is at least 33 characters long:

...
else {
    String str = fileEntry.getName();
    if(str == null || "index.html".equals(str)){
        continue;
    }          
    if(str.length() >= 33 && str.charAt(32) == '9'){
        arrayList.add(str);
    }
}
...

If, however, it is certain that the last character is 9, then do this instead:

...
else {
    String str = fileEntry.getName(); 
    if(str == null || "index.html".equals(str)){
        continue;
    }          
    if(str.charAt(str.length() - 1) == '9'){
        arrayList.add(str);
    }
}
...
Olavi Mustanoja
  • 2,045
  • 2
  • 23
  • 34
  • That's a good idea, but if that wasn't the case, the OP wouldn't get a NullPointerException. He would get an IndexOutOfBoundsException. – JB Nizet Oct 24 '14 at 07:44
0

This will fix it:

String str = fileEntry.getName();
if (str == null || "index.html".equals(str)) {
    continue;
}
if (str.length() >= 33 && str.charAt(32) == '9') {
    arrayList.add(str);
}

We missed one big thing:

final File folder1 = new File("/home3/not_existing_follder");
if (!folder1.exists() || !folder1.isDirectory()){
    System.out.print("Folder! does not exist");
    return;
}

When File is given with an not existing dir, it will return a null. Apply this to both directories and you will be fine.

Beri
  • 11,470
  • 4
  • 35
  • 57
  • It got this error. `Exception in thread "main" java.lang.NullPointerException at readandcopyupdate1.ReadAndCopyUpdate1.listFilesForOldFolder(ReadAndCopyUpdate1.java:38) at readandcopyupdate1.ReadAndCopyUpdate1.main(ReadAndCopyUpdate1.java:15) Java Result: 1` – user3774654 Oct 24 '14 at 07:56
  • I know that It will sound funny, but I had runned it on my linux dir and I had no exception. Do you use any kind of IDE? Can you give us a hint, what is in like 38? If you don't know how to debug, place a system.out.print with different letters in your code, that will help you to find last place in code that was executed before crash. That will help you and mayby us to find the problem. – Beri Oct 24 '14 at 08:09
  • If you lines havn't changes it seems you are passing null instead of File object. – Beri Oct 24 '14 at 08:10
  • On my line 38, i have `*/` (closing of comment) above that I have 7 lines of comment – user3774654 Oct 24 '14 at 08:14
  • Ofcource I assume you did compile your file:) Ok, so try to put some System.out.print for debuggind purposes. Thanks to it, you will find th espot where you get this error. This is one of the oldest ways to debug:) – Beri Oct 24 '14 at 08:17
  • no it's not funny. I just tried that program on server and it ran successfully. But on my localhost (my laptop) It is behaving abnormally. The java compiler on my system ain't broken because I can run "HelloWorld" program. – user3774654 Oct 24 '14 at 08:30
  • But we won't be able to help you without knowlegde what files are you processing. It is your enviroment. Now the best way to find this would be debuggin it.If you don't use IDE use those SOP's. – Beri Oct 24 '14 at 08:38
  • It's solved. I changed `rc.oldFiles.stream().forEach((oldFile) -> {` loop with `for(int i = 0; i < rc.oldFile.size(); i++){` and it worked. – user3774654 Oct 24 '14 at 08:40
  • Ok I found it. We missed one big thing. – Beri Oct 24 '14 at 08:44
  • Look at my comment, you got corrupted dir paths. You need to validate that those dirs exist and are directories, not files. – Beri Oct 24 '14 at 08:46
  • Ok, if my solution fix your problem, you can close this task. – Beri Oct 24 '14 at 08:58