Search code examples
javajava-iofile-processing

Reading Lines of Text from a File


I have a text file containing 5 customers (1 per line), Customer 1, Customer 2, Customer 3, Customer 4 and Customer 5. Using the following code, it reads the 5 lines of text perfectly;


import java.io.*;

public class CustomerIO  {

public void method () {

        try (BufferedReader br = new BufferedReader(new FileReader(new File ("Customers.txt")))) {
            int numberOfLines = readLines();
            String [] text = new String [numberOfLines];

            for (int i = 0; i < numberOfLines; i++) {
                text[i] = br.readLine();        
            }

            for (int i = 0; i < numberOfLines; i++) {
                System.out.println(text[i]);        
            }
        } catch (Exception e) {
            e.printStackTrace();
        }


    private int readLines() {

        try (BufferedReader br = new BufferedReader(new FileReader(new File ("Customers.txt")))) {

            while ((line = br.readLine()) != null) {
                numberOfLines++;
            }

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

However when I change to the following the output is: Customer 2, Customer 4, null


import java.io.*;

public class CustomerIO  {

    String line;
    int numberOfLines = 0;

    public void method () {

        try (BufferedReader br = new BufferedReader(new FileReader(new File ("Customers.txt")))) {

            while (br.readLine() != null) {
                System.out.println(br.readLine());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }


    }

    private int readLines() {

        try (BufferedReader br = new BufferedReader(new FileReader(new File ("Customers.txt")))) {

            while ((line = br.readLine()) != null) {
                numberOfLines++;
            }

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

The main method is contained in the following runner.class file

public class Runner {

    public static void main(String[] args) {

        CustomerIO cus = new CustomerIO ();
        cus.method();
    }
}

Can you help me understand why this is happening? I want to read the customers into an arraylist when its reading in correctly rather than working with a String [].

Thanks


Solution

  • The following code calls readLine() twice per iteration of the loop, which is why you only see every other line:

    while (br.readLine() != null) {
        System.out.println(br.readLine());
    }
    

    You need to assign the returned value to a variable, so you can check for null.

    There are many ways to do that, so I'll show some, in decreasing order of recommendation.

    // Using for loop (recommended)
    //   Pro: Keeps the loop logic with the loop
    //        Limits the scope of the variable
    //        Smallest amount of code (lines of loop code: 2)
    //   Con: Unusual construct
    //        Inline assignment
    for (String line; (line = br.readLine()) != null; ) {
        System.out.println(line);
    }
    
    // Using while loop with inline assignment
    //   Pro: Common construct
    //        Keeps the loop logic with the loop
    //        Small amount of code (lines of loop code: 3)
    //   Con: Variable scope not limited to the loop
    //        Inline assignment
    String line;
    while ((line = br.readLine()) != null) {
        System.out.println(line);
    }
    
    // Using while loop without inline assignment
    //   Pro: Common construct
    //   Con: Loop logic both before and at end of loop
    //        Variable scope not limited to the loop
    //        More code (lines of loop code: 4)
    //        Calling the readLine() method in two places
    String line = br.readLine();
    while (line != null) {
        System.out.println(line);
        line = br.readLine();
    }
    
    // Using break to exit forever loop
    //   Pro: Limits the scope of the variable
    //   Con: Loop logic both before and at end of loop
    //        Using infinite loop and the break statement
    //        More code (lines of loop code: 6)
    for (;;) { // or: while (true)
        String line = br.readLine();
        if (line == null) {
            break;
        }
        System.out.println(line);
    }