在Java中,可以在关闭后重新打开System.in [英] In Java is it possible to re-open System.in after closing it

查看:498
本文介绍了在Java中,可以在关闭后重新打开System.in的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个多线程控制台应用程序,可以从两个不同的来源获取输入。一个是用户输入控制台,另一个是网络。我使用BufferedReader.readline()来获取用户和块的输入,这很好,除非我在等待时收到网络输入。在这种情况下,我需要通过取消readline()来取消阻止用户线程。

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().

我认为取消的最佳方法是关闭System.in并生成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?

推荐答案

无法重新打开 System.in System.out System.err 。底层本机流是连接到其他进程的文件描述符,或者是应用程序无法识别其身份的文件。一旦基础本机文件描述符关闭,就无法重新打开它们。

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.

我能建议的最好的是你创建一个包装器 InputStream System.in 对象的类,并对包装器进行编码以处理 close()作为无操作。或者可能将包装器设置为关闭状态而不实际关闭包装流。

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.

在您的特定用例中,这将无效,因为您需要 从 System.in 中读取时,取消阻止被阻止的线程。因此,在您的情况下,您需要从 System.in 进行非阻塞输入。例如,使用 available()方法来测试是否有任何要从控制台读取的字符。 (通常可以安全地假设,如果 available()返回大于零的数字,您将能够读取整行。)

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.)

(它也可能使用 Selector 实现非阻塞读取,但我认为不可能获得可选择的频道用于 System.in 对象。)

(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.)

请注意 Thread.interrupt()将不起作用。根据javadocs,它只有在您从可中断频道阅读时才有效。

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不是可中断的频道,

  • System.in is not an interruptible channel, and

如果是,那么 interrupt()的记录行为就是频道被中断关闭。

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

这篇关于在Java中,可以在关闭后重新打开System.in的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆