1

I have written a piece of code that counts the number of lines in a file (I wasn't able to find a built-in method that could acheive this in the IO classes). My code below:

try {
    while(!line.equals("null")) {
        line = bufferedReader.readLine();
        a = a + 1;
        System.out.println(a + " " + line);
    }
} catch (NullPointerException N) {}

The problem I'm running into is that the count still increases while the variable 'line' evaluates to "null". I understand why this is the case; the while statement won't check the condition until after the entire code block has been run, in which case 'a' will have increased once again. Solutions I have considered:

1) Set 'a = -1', whereas I currently have 'a = 0' before this block of code 2) Use if statement to break the loop before the count variable is reached. This is how I would modify the code block:

try {
    while(!line.equals("null")) {
        line = bufferedReader.readLine();
        if (line.equals("null")) {break;}
        a = a + 1;
        System.out.println(a + " " + line);
    }
} catch (NullPointerException N) {}

My problem with the above? (1) seems too contrived while (2) seems redundant. I wanted to see if there's a better way to approach this - thanks for your suggestions.

BenWS
  • 521
  • 2
  • 6
  • 20

3 Answers3

8

Unless your file ends with a line that contains the String "null", your code is wrong. You should be comparing to null, not to "null".

And regarding to your original question, you can avoid the extra count by both reading a line and testing for null in the condition of the loop :

while((line = bufferedReader.readLine()) != null) {
    a = a + 1;
    System.out.println(a + " " + line);
}
Eran
  • 387,369
  • 54
  • 702
  • 768
  • Interestingly, checking for the string "null" for this loop does seem to work without any problems; in any case I agree I should be checking for the null rather than "null". And reading the line within the condition of the loops does solve my problem. Thanks for your answer! – BenWS Mar 13 '16 at 12:37
  • @BenWS: no, your check doesn’t work, you are just catching the `NullPointerException` which arises when you try to invoke `equals(…)` on a `null` reference. You could put anything into the parameter string, as long as it doesn’t appear in the text file, the outcome would be the same. That’s obviously not working, that’s broken with a `“happens to look almost correct” outcome. – Holger Mar 14 '16 at 09:47
5

There is a LineNumberReader class which does exactly what you want.

try(LineNumberReader  lnr = new LineNumberReader(new FileReader(new File("file.txt"))) {
    lnr.skip(Long.MAX_VALUE);
    linesCount = lnr.getLineNumber() + 1; //because it's index from 0
}
Petr Mensik
  • 26,874
  • 17
  • 90
  • 115
4

Other (good) answers notwithstanding, I think it's worth posting an alternate, simple solution:

long lineCount = Files.lines(Paths.get(filename)).count();
Bohemian
  • 412,405
  • 93
  • 575
  • 722
  • Side-note: `Files.lines` return a `Stream` that should be closed , for example with a try-with-resources. – Tunaki Mar 13 '16 at 19:14