Search code examples
javajava.util.scannerfilereaderjava.nio.file

Attempting to create objects in loop while reading files and getting error


I'm creating a program for school that reads a text file, stores the data into variables, and then creates an object to pass the data into for later use. I'm using a scanner class for file reading at this moment. I am getting an error however.

Exception at java.lang.NullPointerException
at FileRead.readfile(FileRead.java:22)
at FileRead.init(FileRead.java:73)
at FileRead.main(FileRead.java:13)

I'm not quite sure what null pointer exception is, but here is my code from FileRead:

The main method isn't all that interesting but here it is

public class FileRead {    
    public static void main(String args[]) throws FileNotFoundException {    
    final File folder = new File("/home/work/txt");    

    init(folder);        
}

Here is my init() method

public static void init(final File folder) throws FileNotFoundException {    
    String foo, bar;
    int slime, grit, ball, funk;
    
    for (final File fileEntry: folder.listFiles()) {
        if(fileEntry.isDirectory()) {
            init(fileEntry);    
        } else {
            readfile(fileEntry);
        }    
    }

Here is readfile()

public static void readfile(final File folder) throws FileNotFoundException  {        
    int count = folder.list().length;        
    DT[] dts = new DT[count];    
    File file = folder;    
    String foo, bar;    
    int slime, grit, ball, funk;    
    Scanner input = new Scanner(file);        
    int i = 0;
    
    while (input.hasNextLine()) {        
        foo = input.nextLine();        
        bar = input.nextLine();
        slime = input.nextInt();
        grit = input.nextInt();
        ball = input.nextInt();
        funk = input.nextInt();

        dts[i] = new DT(foo, bar, slime, grit, ball, funk);
        i++;
        break;    
    }            
}

This is all for the file reader, the other class is much simpler. Here is DT:

private String foo, bar; privates int slime, grit, ball, funk;

public DT(String foo, String bar, int slime, int grit, int ball, int funk) {
    this.foo = foo;
    this.bar = bar;
    this.slime = slime;
    this.grit = grit;
    this.ball = ball;
    this.funk = funk;
    
    ds(foo, bar, slime, grit, ball, funk);
}

public static void ds(String t, String g, int a, int st, int sn, int s) {    
    System.out.println(t + "\n" + g + "\n" + a + "\n" + st + "\n" + sn + "\n" + s);           
}

I'm running this on an Ubuntu VM if that helps. I would really appreciate help with with this, thanks!


Solution

  • Your DT class got me wondering, it should be a data class, shouldn't it? But your data class has no instance variables and also only provides static methods to set the content. The keyword static specifies a method as a class method, meaning that it can only be accessed over DT.methodName() and not over the object, also it can only edit static variables, meaning you can't use them for a data class. The NullPointerException probably occurs in this line: dts[i].set(foo, bar, slime, grit, ball, funk); Even though you created a fixed-sized array in this line: DT[] dts = new DT[count]; you also have to create the DT-object on each index. Like this: dts[i] = new DT(); A NullPointerException tells you, that a variable doesn't have anything assigned to it, meaning dts[i] points to nothing (null), that's why you first have to assign something to it to use the method set() I would recommend you something like this for your data class:

    public class DT {
        private String foo, bar;
        private int slime, grit, ball, funk;
        public void ds() {
            System.out.println(foo + "\n" + bar + "\n" + slime + "\n" + grit + "\n" + ball + "\n" + funk);
        }
        public DT(String foo, String bar, int slime, int grit, int ball, int funk) {
            this.foo = foo;
            this.bar = bar;
            this.slime = slime;
            this.grit = grit;
            this.ball = ball;
            this.funk = funk;
        }
    }
    

    and then create your object like this: dts[i] = new DT(foo, bar, slime, grit, ball, funk); Last but not least, you should use class, method and variable names that are more meaningful so that other people know what the class is for

    The error occurs because folder.list() returns null, cause it is a file, you test this before in init() with .isDirectory(), and not a directory with sub-directorys/files. To solve this problem you can just enter a fixed number or don't use an array at all, as you only have one element in it, because you break the loop after reading one DT

    while (input.hasNextLine()) {        
            foo = input.nextLine();        
            bar = input.nextLine();
            slime = input.nextInt();
            grit = input.nextInt();
            ball = input.nextInt();
            funk = input.nextInt();
    
            dts[i] = new DT(foo, bar, slime, grit, ball, funk);
            i++;
            break;    // here you close the loop, regardless if input has a next line or not
        } 
    

    However, if you have multiple DTs in one file, remove the break and use an ArrayList instead

    Update - for new error NoSuchElementException This exception means that you are trying to read a line, but there is no line left in the file. Maybe your file doesn't have all the required elements in it, however, if you want to make your code more robust use exception handling, in this example you would need something like this:

    try{
        // your code here (readLine(), etc)
    } catch(NoSuchElementException ex){
        // exception handling, like printing that the file doesn't have the correct format
        Syste.out.println("Wrong data format in file "+folder);
    }
    

    as you can see at my example, your variable name is actually misleading, as the "folder" is in fact a file also, as I already mentioned, if you're file contains multiple DTs remove the break in the while loop, or if one file only contains one DT, use a simple DT object instead of a list