【问题标题】:In Java is it possible to re-open System.in after closing it在Java中是否可以在关闭 System.in 后重新打开它
【发布时间】:2014-12-04 05:08:59
【问题描述】:

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

我认为最好的取消方法是关闭 System.in 并使 readline() 抛出异常。在那之后,虽然我需要重新打开它。这可能吗?

【问题讨论】:

标签: java multithreading io console


【解决方案1】:

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

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

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

(它也可以使用Selector 实现非阻塞读取,但我认为不可能为System.in 对象获取“可选通道”。)


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

  • System.in 不是可中断通道,并且

  • 如果是,那么记录在案的 interrupt() 的行为是通道被中断关闭。

【讨论】:

  • 但 user1379635 想使用 close() 来中断线程。使其成为无操作将无法实现这一点,因此无需调用 close() :) 将包装器设置为“关闭”状态不会中断块线程。
  • 感谢您的回答。看来我得重新设计了。
【解决方案2】:

我遇到了同样的问题,我觉得奇怪,至少可以说,java 本身没有解决这个问题:我们不是遗漏了什么吗?

无论如何,感谢 Stephen C,这里有一个将他的想法用于匿名类的小例子(内联,在为 system.in 创建扫描仪时)

(我使用FilterInputStream而不是InputStream,这样我可以将System.in传递给构造函数)

希望对你有用

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");
    }
}

【讨论】:

    猜你喜欢
    • 2013-12-08
    • 1970-01-01
    • 2018-04-03
    • 2020-03-10
    • 1970-01-01
    • 2020-07-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多