In Java is it possible to re-open System.in after closing it

It is not possible to reopen System.in, System.out or System.err. The underlying native streams are file descriptors that are connected to other processes, or to files whose identity your application cannot discern. Once the underlying native file descriptors are closed, it is not possible to reopen them.

The best I can suggest is that you create a wrapper InputStream class for the System.in object, and code the wrapper to treat close() as a no-op. Or maybe set the wrapper into a "closed" state without actually closing the wrapped stream.

In your specific use-case, that won't work, because you "need" to unblock the thread that is blocked while reading from System.in. So in your case, you will need to do non-blocking input from System.in. For example, use the available() method to test if there are any characters to read from the console. (It is typically safe to assume that if available() returns a number greater than zero you will be able to read an entire line.)

(It might also be able to implement non-blocking reads using a Selector, but I don't think that it is possible to obtain a "selectable channel" for the System.in object.)


Note that Thread.interrupt() won't work. According to the javadocs, it will only work if you are reading from an interruptible channel.

  • System.in is not an interruptible channel, and

  • if it was, then the documented behaviour for interrupt() is that the channel gets closed by the interrupt.


I'm having the same problem, and I found it odd, to say the least, that this problem is not adressed by java itself : aren't we missing something ?

anyway, thanks to Stephen C, and here is a little example for using his idea with an anonymous class (inline, when creating your scanner for system.in)

(I used FilterInputStream instead of InputStream, so that I could pass System.in to the constructor)

hope this is of some use to you

public class MultiopenScanner {
    public static int scanInt() throws IOException{
        //Scanner sc = new Scanner(System.in);
        Scanner sc = new Scanner(new FilterInputStream(System.in){public void close(){}});
        int res = sc.nextInt();
        sc.close();
        return res;
    }

    public static void main(String[] args) throws IOException {
        int i=1;
        while (i>0) {
            System.out.println("Give me an int please : ");
            //some might need this : System.out.flush();
            i = scanInt();
            System.out.println("got "+i);
        }
        System.out.println("done");
    }
}