Подтвердить что ты не робот

Как подключить вход к программе Java с помощью bash

Моя программа 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

Как я могу исправить программу, чтобы я мог подключать вход для тестирования, но запуск программы обычно позволяет пользователям вводить ввод также на стандартный ввод?

4b9b3361

Ответ 1

Исправлено. После завершения подачи трубопровода readLine() продолжал возвращать null, поэтому бесконечный цикл продолжал цикл.

Исправление состоит в том, чтобы выйти из бесконечного цикла, когда readLine() возвращает значение null.

Ответ 2

Что я делаю неправильно?

Я не вижу причин, почему этот фрагмент будет вести себя так. Я подозреваю, что проблема в том, что вы нам не показали...

Например, какую версию echo вы используете? Оболочка встроена? Стандартный в '/bin'? Какой-нибудь фанковый на вашем пути поиска?

Вы можете попробовать несколько простых экспериментов, чтобы определить, находится ли проблема на уровне оболочки/команды или в приложении Java; например.

$ echo hi > tmp
$ cat tmp
$ java -classpath ../src test.TestProgram < tmp
$ cat tmp | java -classpath ../src test.TestProgram

и так далее.

Если ни один из этих экспериментов не дает никаких подсказок, отправьте реальный исходный код Java небольшой программы, которая демонстрирует вашу проблему.

(И, как справедливо указывает @trashgod, вы можете "выполнить пальцем" шаг сборки и запустить версию программы, которая больше не соответствует вашему исходному коду.)

Ответ 3

У вас есть while(true), поэтому бесконечный цикл - это то, что вы собираетесь получить.

Добавление break где-то в цикле является одним из способов его исправления. Но это не очень хороший стиль, потому что читателю нужно поохотиться вокруг цикла, чтобы узнать, если и когда он выйдет.

Намного лучше сделать ваш оператор while четко показать, что условие выхода:

String inputStr = "";
while(inputStr != null) {
    inputStr=bufReader.readLine(); 
    if(inputStr != null) {
        ...
    } else {
        System.out.println("inputStr is null");
    }
}

Ответ 5

Мне нравится тонкий ответ, только я склоняюсь к нему немного по-другому. это базовый шаблон, который я использую для чтения потока текста, строка за строкой.

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
}