Ответ 1
Исправлено. После завершения подачи трубопровода readLine()
продолжал возвращать null
, поэтому бесконечный цикл продолжал цикл.
Исправление состоит в том, чтобы выйти из бесконечного цикла, когда readLine()
возвращает значение null.
Моя программа 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: Вход в строку командной строки в Java
Как я могу исправить программу, чтобы я мог подключать вход для тестирования, но запуск программы обычно позволяет пользователям вводить ввод также на стандартный ввод?
Исправлено. После завершения подачи трубопровода readLine()
продолжал возвращать null
, поэтому бесконечный цикл продолжал цикл.
Исправление состоит в том, чтобы выйти из бесконечного цикла, когда readLine()
возвращает значение null.
Что я делаю неправильно?
Я не вижу причин, почему этот фрагмент будет вести себя так. Я подозреваю, что проблема в том, что вы нам не показали...
Например, какую версию echo
вы используете? Оболочка встроена? Стандартный в '/bin'? Какой-нибудь фанковый на вашем пути поиска?
Вы можете попробовать несколько простых экспериментов, чтобы определить, находится ли проблема на уровне оболочки/команды или в приложении Java; например.
$ echo hi > tmp
$ cat tmp
$ java -classpath ../src test.TestProgram < tmp
$ cat tmp | java -classpath ../src test.TestProgram
и так далее.
Если ни один из этих экспериментов не дает никаких подсказок, отправьте реальный исходный код Java небольшой программы, которая демонстрирует вашу проблему.
(И, как справедливо указывает @trashgod, вы можете "выполнить пальцем" шаг сборки и запустить версию программы, которая больше не соответствует вашему исходному коду.)
У вас есть while(true)
, поэтому бесконечный цикл - это то, что вы собираетесь получить.
Добавление break
где-то в цикле является одним из способов его исправления. Но это не очень хороший стиль, потому что читателю нужно поохотиться вокруг цикла, чтобы узнать, если и когда он выйдет.
Намного лучше сделать ваш оператор while
четко показать, что условие выхода:
String inputStr = "";
while(inputStr != null) {
inputStr=bufReader.readLine();
if(inputStr != null) {
...
} else {
System.out.println("inputStr is null");
}
}
Вы можете использовать именованные каналы (fifos), чтобы обеспечить как нормальный вход через управляющий терминал /dev/tty
(или /dev/stdin
), так и входной канал через входной сигнал fifo.
Смотрите: Перенаправление ввода приложения (java), но все же разрешение stdin в BASH
Мне нравится тонкий ответ, только я склоняюсь к нему немного по-другому. это базовый шаблон, который я использую для чтения потока текста, строка за строкой.
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
}