0

I wrote a tiny Press Enter to Continue module but Java won't let me close the BufferedInputStream after I read from it. If I close it it errors "Stream closed" when I try to call the module again, even though I try to open it again first.

import java.io.*;

final public class PressEnter {
    public static void toContinue() {
        try {
            BufferedInputStream buff=new BufferedInputStream(System.in);
            int in=buff.read();
            buff.close();
        }
        catch (IOException e) { System.out.println("Error: "+e.getMessage()); }
    }
}

I don't close the BufferedInputStream and it works fine, as many times as I call it. Leaving in buff.close it errors.

public class TestPressEnter {
    public static void main(String[] args) {
        System.out.print("Press Enter To Continue...");
        PressEnter.toContinue();
        System.out.println("Continuing...");

        System.out.print("Press Enter To Continue Again...");
        PressEnter.toContinue();
        System.out.println("Continuing...");
    }
}
ƒrequency
  • 31
  • 5
  • 3
    Remove `buff.close();`. You are closing `System.in`. – Andy Turner Apr 03 '19 at 12:11
  • 1
    The problem is that `BufferedInputStream.close()` will close the passed stream (`System.in` in your case) as well, which is something you don't want to happen. – Thomas Apr 03 '19 at 12:11

2 Answers2

0

You can not re-open a closed Scanner even if you re-instantiate it. See Why is not possible to reopen a closed (standard) stream?

The BufferedInputStream is a wrapper around the underlying InputStream which in this case is System.in. So calling close on the wrapper will also close the underlying stream.

You should instantiate the Scanner out of the method call and instead use it there to read it. You could create a new method which could close it after you are done with reading in your main method.

Murat Karagöz
  • 26,294
  • 9
  • 70
  • 97
0

The general contract for OutputStream's close:

public void close() throws IOException Closes this output stream and releases any system resources associated with this stream. The general contract of close is that it closes the output stream. A closed stream cannot perform output operations and cannot be reopened.

PrintStream's

public void close() Close the stream. This is done by flushing the stream and then closing the underlying output stream.

The only advice I can give you is that you should not write asymmetrical code, that is, don't delegate the closing of resources your code has created to somewhere else.

Even if in your case it might seemed sensible to close the wrapper stream, the fact is that you should not because you are closing a stream opened somewhere else.

RealSkeptic
  • 32,074
  • 7
  • 48
  • 75
Manjeet Brar
  • 894
  • 1
  • 10
  • 27