如何避免 Java.util.Scanner 在后台运行时抛出 NoSuchElementException 异常?
2024-03-08 11:57:46
使用 Java.util.Scanner 在后台运行时避免 NoSuchElementException
引言
Java 程序通常使用 java.util.Scanner
类从标准输入中读取数据。然而,当 Java 程序在后台运行时,使用 &
标记,可能会遇到 java.util.NoSuchElementException
异常。本文将深入探讨这个问题的原因,并提供两种可行的解决方案。
问题:背景运行时停止响应
当 Java 程序在后台运行时,标准输入会关闭,导致 Scanner
无法读取任何数据。这会导致以下问题:
- 使用
nohup java -jar my.jar &
时,程序会抛出java.util.NoSuchElementException
异常,表明程序正在后台运行。 - 使用
java -jar my.jar &
时,程序会停止运行,并在终端输出[1]+ 已停止
。
解决方案
解决方案 1:使用 ProcessBuilder
ProcessBuilder
可以创建一个新进程,并指定其标准输入、标准输出和标准错误流。通过将标准输入重定向到一个管道,我们可以避免 Scanner
在后台运行时遇到问题:
ProcessBuilder pb = new ProcessBuilder("java", "-jar", "my.jar");
pb.redirectInput(ProcessBuilder.Redirect.PIPE);
Process process = pb.start();
process.getOutputStream().write("Hello, world!".getBytes());
Scanner scanner = new Scanner(process.getInputStream());
while (scanner.hasNextLine()) {
System.out.println(scanner.nextLine());
}
process.waitFor();
解决方案 2:使用 System.in.available()
System.in.available()
方法可以检查标准输入流中是否有可用的字节。如果流中没有可用字节,则表示标准输入已关闭,程序正在后台运行。我们可以使用以下代码来检测此情况:
while (System.in.available() > 0) {
String s = scanner.nextLine();
System.out.println("s = " + s);
}
System.out.println("I'm running in the background!");
结论
通过使用 ProcessBuilder
或 System.in.available()
,我们可以解决 java.util.Scanner
在后台运行时遇到的问题,并确保程序正常读取输入数据。
常见问题解答
-
为什么在后台运行时会出现这个问题?
因为标准输入在后台运行时关闭了。 -
这两个解决方案有什么区别?
ProcessBuilder
创建一个新进程,并允许我们控制标准输入,而System.in.available()
允许我们检查标准输入流是否关闭。 -
哪个解决方案更好?
取决于具体情况,ProcessBuilder
更通用,而System.in.available()
更简单。 -
是否还有其他解决方案?
还有一些其他解决方案,如使用管道或死信管道,但它们更复杂。 -
如何判断程序是否正在后台运行?
可以使用ProcessBuilder.isRunning()
方法或System.in.available()
方法来检查。