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

console, io, java, multithreading

Solution

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.

Problem

I have a multithreaded console app that gets input from two different sources. One is the user typing into the console and the other is the network. I use a BufferedReader.readline() to get input from the user and that blocks, which is good, unless I receive network input while I'm waiting. In that case I need to unblock the user thread by canceling readline(). I figured the best way to cancel that is to close System.in and make readline() throw an exception. After that though I'd need to re-open it. Is that possible?

Original source

Related problems