try with resources closing the resources unexpectedly

I am trying to invoke the following method inside a while loop. First time, it invokes fine but on 2nd loop execution, it throws an IOException

public String getInputString(String prompt){
        System.out.print(prompt);
        String inputLine = null;

        try(BufferedReader br = new BufferedReader(new InputStreamReader(System.in))){
            inputLine = br.readLine();
            if(inputLine.length() == 0){
                return null;
            }
        }
        catch(IOException e){
            e.printStackTrace();
        }

        return inputLine;
    }

I am getting this IOException:

 java.io.IOException: Stream closed
    at java.io.BufferedInputStream.getBufIfOpen(BufferedInputStream.java:162)
    at java.io.BufferedInputStream.read(BufferedInputStream.java:325)
    at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:283)
    at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:325)
    at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:177)
    at java.io.InputStreamReader.read(InputStreamReader.java:184)
    at java.io.BufferedReader.fill(BufferedReader.java:154)
    at java.io.BufferedReader.readLine(BufferedReader.java:317)
    at java.io.BufferedReader.readLine(BufferedReader.java:382)
    at ch5.GameHelper.getInputString(GameHelper.java:14)
    at ch5.SimpleDotComTestDrive.main(SimpleDotComTestDrive.java:19)

On the other hand, it is working fine when i try to execute it as follows:

        try{
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            inputLine = br.readLine();
            if(inputLine.length() == 0){
                return null;
            }
        }
        catch(IOException e){
            e.printStackTrace();
        }

What is the reason for such a behaviour?

Jon Skeet
people
quotationmark

I suspect you're calling getInputString more than once.

The first time, it should work fine - but then you're closing System.in (by closing the BufferedReader wrapping InputStreamReader wrapping System.in)... which means the next time you try to read from System.in, you won't be able to.

If you remove the try-with-resources statement, you could still have problems, because you'll be creating multiple readers around the same stream - if one of those reads more input than you actually use, it won't be available later on.

I suggest you create a BufferedReader wrapping an InputStreamReader wrapping System.in once, at the start of your program, and use that BufferedReader instance everywhere.

people

See more on this question at Stackoverflow