Wusiji
Wusiji

Reputation: 599

BufferedReader returns null second use

I'm using this custom class to simulate the system.console while debugging in eclipse. What's confusing me is that reader = new BufferedReader(new InputStreamReader( System.in)); is returning null after the second called of readLine.

I thought it was because I had closed System.in, but according to oracle

The close method of InputStream does nothing.

So now I'm stumped. Here's the code:

public class CustomConsole {
    public String readLine(String format, Object... args) {
        if (System.console() != null) {
            return System.console().readLine(format, args);
        }
        BufferedReader reader = null;
        String line = null;
        try {
            System.out.print(String.format(format, args));
            reader = new BufferedReader(new InputStreamReader(
                    System.in));
            line = reader.readLine();
        } catch (IOException e) {
            Logger.fatal(e.getMessage());
            System.exit(-1);
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    Logger.error("CustomConsole.readLine(): BufferedReader could not be closed");
                    e.printStackTrace();
                }
            } else {
                Logger.error("CustomConsole.readLine(): BufferedReader is null");
            }
        }
        return line;
    }

    public String readLine() {
        return readLine("", "");
    }

    public char[] readPassword(String format, Object... args) {
        if (System.console() != null) return System.console().readPassword(format, args);
        return this.readLine(format, args).toCharArray();
    }
}

Upvotes: 2

Views: 1009

Answers (2)

user2920760
user2920760

Reputation:

InputStream is an abstract class. System.in will give you an object of a subclass of InputStream that may have the close method implemented differently.

How about modifying the class to have a field to hold the BufferedReader you create? Something like this:

public class CustomConsole {
    private BufferedReader reader;

    public String readLine(String format, Object... args) {
        if (System.console() != null) {
            return System.console().readLine(format, args);
        } else if (reader == null) {
            reader = new BufferedReader(new InputStreamReader(
                System.in));
        }

        return reader.readLine();
        ...

Add the exception handling code as you wish appropriate. You don't have to close the reader.

Upvotes: 0

Cyrille Ka
Cyrille Ka

Reputation: 15523

The close method of InputStream does nothing, but InputStream can be subclassed and this subclass can implement close to be anything. This is the case with BufferedInputStream for example which, on my machine, is the type of System.in.

When you are closing your reader, you are closing all the underlying resources and therefore closing System.in. Nothing can then be read afterwards.

To solve this, you can simply remove the code that close the reader altogether, and it will work. It may seem odd to recreate a BufferedReader everytime, then just store it as a field of your CustomConsole and reuse it next time. Anyway you won't need to close it ever, since it is just a wrapper of a wrapper around System.in, which is handled by the system.

Rewriting your class in that spirit would produce something like this:

public class CustomConsole {

    private BufferedReader reader;

    public String readLine(String format, Object... args) {
        if (System.console() != null) {
            return System.console().readLine(format, args);
        }

        if (reader == null) {
            reader = new BufferedReader(new InputStreamReader(System.in));
        }

        try {
            return reader.readLine();
        } catch (IOException e) {
            Logger.fatal(e.getMessage());
            System.exit(-1);
            return null;
        }
    }

// ....

Upvotes: 2

Related Questions