Search code examples
javafile-ioiotry-catch

Even though the try block can read the file, the method still returns null. How do I get it to return the expected string?


So the test runs to see if the method can read the file and return its contents. I've tried different alterations and this is what I've come to so far. I was able to print out all the necessary contents in the while loop, but once outside that loop, fileContents returns "null".

public static String readTestResults(String fileName) {

        BufferedReader reader;
        String fileContents = " ";

        try {
            reader = new BufferedReader(new FileReader(fileName));
            fileContents = reader.readLine();

            while (fileContents != null) {
                System.out.println(fileContents);
                fileContents = reader.readLine();
            }
            reader.close();
            System.out.println("test: " + fileContents);
            return fileContents;
        }

        catch (IOException e) {
            e.printStackTrace();
        }

        System.out.println("Print if code reaches here");
        return fileContents;

I've added multiple print statements to try and pinpoint where the code could be bugged. It never reaches to final one. So far my results are:

Alex,Smith,99,A
Jolene,Schmidt,100,A
Mackinzie,Jensen,86,B
test: null

I need it to return just that list of names but just returns null.

I believe it could be a format error of mine but as now I am stumped. Any help would be greatly appreciated!


Solution

  • Start by having a look at the JavaDocs for BufferedReader#readline, it clearly states "or null if the end of the stream has been reached without reading any characters".

    Then look at your loop exit condition, while (fileContents != null) {, this would mean that fileContents will be null after the loops exit, which is why when you do return fileContents; you're returning null

    If you just want to return a single String representing the entire contents of the file, you could, instead, do something like...

    public static String readTestResults(String fileName) {
        try (BufferedReader reader = new BufferedReader(new FileReader(fileName))) {
            StringJoiner joiner = new StringJoiner(System.lineSeparator());
            String line = null;
            while ((line = reader.readLine()) != null) {
                joiner.add(line);
            }
            return joiner.toString();
        } catch (IOException e) {
            e.printStackTrace();
        }
    
        return null;
    }
    

    Now, personally, I wouldn't consume the exception here, instead I'd throw it, for example...

    public static String readTestResults(String fileName) throws IOException {
        try (BufferedReader reader = new BufferedReader(new FileReader(fileName))) {
            StringJoiner joiner = new StringJoiner(System.lineSeparator());
            String line = null;
            while ((line = reader.readLine()) != null) {
                joiner.add(line);
            }
            return joiner.toString();
        }
    }
    

    It then becomes the responsibility of the caller to handle the error, which makes more sense then returning a null or empty String.

    You may also find it easier use Files#readAllLines which will return a List<String> - this will be easier to parser IMHO.

    You'll also want to take a look at The try-with-resources Statement to understand how that code is actually working and why you should be using it.