0

Hi I am loading a file into my program and assigning each value (stored on a new line to a array) I cant seem to spot why the array holding the file content is null in each index.

    private void readAndProcessWords() {
    try {
        FileReader _fr = new FileReader(FILEPATH);
        BufferedReader textReader = new BufferedReader(_fr);

        int numLines = getNumLines(textReader);
        String[] words = new String[numLines];

        for(int i=0;i<numLines;i++){
            words[i] = textReader.readLine();
            System.out.println(words[i]);
        }
        //clears memory reserved for this buffered reader
        textReader.close();

    } catch(IOException e) {
        System.out.println(e);
    }
}

private int getNumLines(BufferedReader textReader) throws IOException{
    String line;
    int numLines =0;

    while((line = textReader.readLine()) != null){
        numLines++;
    }
    return numLines;    
}
}

Solution: add the below code above the loop to 'reset' the file reader

_fr = new FileReader(FILEPATH);
        textReader = new BufferedReader(_fr);
5
  • 2
    Welcome to Stack Overflow, please take the Tour. Questions seeking debugging help ("why isn't this code working?") must include the desired behavior, a specific problem or error and the shortest code necessary to reproduce it in the question itself. Questions without a clear problem statement are not useful to other readers. See How to create a Minimal, Complete, and Verifiable example. Commented Aug 3, 2014 at 17:41
  • Use a debugger to trace execution. Commented Aug 3, 2014 at 17:42
  • What do think while((line = textReader.readLine()) != null){ does? Commented Aug 3, 2014 at 17:45
  • 2
    i would state that you have already consumed your file with getNumeLines(), hence you are at end of file when starting to parse lines. Commented Aug 3, 2014 at 17:47
  • Consider using Guava and code similar to this: final URL resource = Resources.getResource("path/to/file.txt"); final List<String> lines = Resources.readLines(resource, Charset.defaultCharset()); Commented Aug 3, 2014 at 17:48

3 Answers 3

4

The easiest solution is to recreate your Reader, the issue is that calling getNumLines() moves the position in your BufferedReader to the end of file.

BufferedReader textReader = new BufferedReader(_fr);
int numLines = getNumLines(textReader); // <-- textReader is at EOF after this.
textReader.close();
textReader = new BufferedReader(_fr);
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for everyone thoughts! the suggestion above is indeed causing the issue. I amended with question with the fix accounting for this. I needed to add a additional line to make a new file reader.
Just a reminder that when you close the textReader you probably want to do that in either a finally block or using try-with resources in Java 7 to clean up the resource properly in the case of an exception.
1

Instead of reading your file twice to get the line count (which is slow, annoying, and will not work if the file changes between the two calls), read the lines into a variable-sized list:

private void readAndProcessWords() {
    try {
        FileReader _fr = new FileReader(FILEPATH);
        BufferedReader textReader = new BufferedReader(_fr);

        List<String> words = new ArrayList<>();
        String line;
        while ((line = textReader.readLine()) != null) {
            words.add(line);
        }
        textReader.close();

        for (String word : words) {
            System.out.println(word);
        }
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}

Good news: this functionality already exists, so you don't need to rewrite it.

private void readAndProcessWords() {
    try {
        List<String> words = Files.readAllLines(Paths.get(FILEPATH));

        for (String word : words) {
            System.out.println(word);
        }
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}

Comments

0

Since a buffered reader is an object you pass it as a reference to the getNumLines() not as a copy, so you end up getting a null when you .readLine() on the same buffered reader you sent to the getNumLines() because you have already run .readLine() to its limit.

After running getNumLines() close and reopen the document with a new buffered reader.

I also remember there being a Mark() and Recall() method for buffered reader in java that could also serve as a work around.

I think like.

        FileReader _fr = new FileReader(FILEPATH);
        BufferedReader textReader = new BufferedReader(_fr);


        textReader.Mark();


        int numLines = getNumLines(textReader);


        textReader.Recall();


        String[] words = new String[numLines];

        for(int i=0;i<numLines;i++)
        {
            words[i] = textReader.readLine();
            System.out.println(words[i]);
        }
        //clears memory reserved for this buffered reader
        textReader.close();

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.