我的Java程序正在监听标准输入:
InputStreamReader isReader = new InputStreamReader(System.in);
BufferedReader bufReader = new BufferedReader(isReader);
while(true){
try {
String inputStr = null;
if((inputStr=bufReader.readLine()) != null) {
...
}
else {
System.out.println("inputStr is null");
}
}
catch (Exception e) {
...
}
}
现在,我想从bash管道输入到这个程序。我尝试了以下方法:
echo "hi" | java -classpath ../src test.TestProgram
但它只是打印inputStr is null
无限次。我做错了什么?
编辑1:更新了问题以包含更多代码/上下文。
编辑2:
看起来我遇到了与此OP相同的问题:Command Line Pipe Input in Java
如何修复程序以便我可以输入管道进行测试,但是正常运行程序还允许用户在标准输入上输入输入?
答案 0 :(得分:5)
修正了它。输入管道完成后,readLine()
继续返回null
,因此无限循环保持循环。
修复是在readLine()
返回null时从无限循环中断。
答案 1 :(得分:4)
你有while(true)
,所以你将获得无限循环。
在循环中的某处添加break
是修复它的一种方法。但这并不是一种好的风格,因为读者必须在循环中寻找是否以及何时退出。
最好让你的while
陈述清楚地显示退出条件是什么:
String inputStr = "";
while(inputStr != null) {
inputStr=bufReader.readLine();
if(inputStr != null) {
...
} else {
System.out.println("inputStr is null");
}
}
答案 2 :(得分:3)
我做错了什么?
我认为没有理由说明代码片段的行为方式。我怀疑问题出在你没有告诉我们的事情上......
例如,您使用的是哪个版本的echo
?壳内置? '/ bin'中的标准版本?你的搜索路径上有一些时髦的东西?
您可以尝试一些简单的实验来确定问题是在shell /命令级别还是在Java应用程序中; e.g。
$ echo hi > tmp
$ cat tmp
$ java -classpath ../src test.TestProgram < tmp
$ cat tmp | java -classpath ../src test.TestProgram
等等。
如果这些实验都没有产生任何线索,请发布一个演示您问题的小程序的真实Java源代码。
(正如@trashgod正确地指出的那样,你可能会在构建步骤中“胖指”,并且正在运行不再与源代码匹配的程序版本。)
答案 3 :(得分:1)
您可以考虑使用命名管道(fifos)来允许通过控制终端/dev/tty
(或/dev/stdin
)的正常输入和通过输入fifo的管道输入。
请参阅:Redirecting input of application (java) but still allowing stdin in BASH
答案 4 :(得分:1)
我喜欢苗条的答案,只是我倾向于处理它有点不同。这是我用来逐行读取文本流的基本模板。
try {
// Wrap the System.in inside BufferedReader
// But do not close it in a finally block, as we
// did no open System.in; enforcing the rule that
// he who opens it, closes it; leave the closing to the OS.
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String line;
while ((line = in.readLine()) != null) {
// TODO: Handle input line
}
// Null was received, so loop was aborted.
} catch (IOException e) {
// TODO: Add error handler
}
如果我正在阅读文件,我会略微更改它,以便像这样关闭文件
try {
File file = new File("some_file.txt");
// Wrap the System.in inside BufferedReader
// But do not close it in a finally block, as we
// did no open System.in; enforcing the rule that
// he who opens it, closes it; leaves the closing to the OS.
BufferedReader in = new BufferedReader(new FileReader(file));
try {
String line;
while ((line = in.readLine()) != null) {
// TODO: Handle input line
}
// Null was received, so loop was aborted.
} finally {
try {
in.close();
} catch (IOException e) {
}
}
} catch (IOException e) {
// TODO: Add error handler
}