Печать вывода другой программы в текстовую область java

Я создаю графический интерфейс с использованием Java. Этот графический интерфейс запускает программу из командной строки, используя класс ProcessBuilder.

Немного информации о запущенном процессе: из командной строки он создает другое окно и выводит информацию в указанное окно.

В моем окне графического интерфейса у меня есть текстовая область, куда я хотел бы перенаправить указанный вывод. Первоначально я намеревался использовать объект SwingWorker, чтобы постоянно проверять наличие дополнительных выходных данных и не задерживать графический интерфейс. Чтобы проверить и убедиться, что у меня есть исходный синтаксис (даже без графического интерфейса), я подумал, что напечатаю вывод из окна вторичного процесса в System.out. Однако что-то кажется неправильным, поскольку я вижу вывод в окне вторичного процесса, но не в терминале, с которого я работаю.

Выдержка из кода выглядит следующим образом:

Process p = pb.start(); 
Scanner s = new Scanner(p.getInputStream());

SwingWorker pipe = new SwingWorker<String, Void> (){
    public String doInBackground(){
        while(run){
            if(s.hasNextLine()){
                System.out.println("S has next!");
                System.out.println(s.nextLine());
            }
        }
        return null;
    }
};
pipe.execute();

Логический запуск определен в другом месте программы и устанавливается в false, когда процесс p завершается или завершается принудительно (дополнительный вопрос: это действительно плохая идея? Мне кажется, что это может быть...).

Кто-нибудь знает, почему я никогда не получаю никакого вывода, когда вижу, что он печатается в другом окне? Первоначально моей реакцией было использовать p.getOutputStream(), но Scanner не принимает outputStream в качестве параметра.

Спасибо за ваше время.


person RCC    schedule 05.01.2010    source источник


Ответы (2)


Вы также должны сканировать p.getErrorStream() - некоторые программы пишут в STDERR, который неотличим от STDOUT при запуске из командной строки. Как правило, рекомендуется потреблять оба потока, так как если какой-либо из них не используется, это может привести к зависанию внешнего процесса.

person Alex Vigdor    schedule 05.01.2010
comment
На самом деле оказывается, что все, что программа печатала в окно, на самом деле печаталось в STDERR. Интересно. Спасибо! - person RCC; 06.01.2010

Если внешний процесс записывает свой вывод в собственное окно, почти наверняка вывод НЕ записывается в STDOUT, который вы читаете с помощью своего кода. Если бы это было так, то выходные данные внешней программы появлялись бы как в ее окне, так и в сеансе командной строки, из которого он был запущен (если он существовал). Без доступа к источнику внешней программы маловероятно, что вы сможете перехватить ее вывод, если только авторы не предусмотрели эту функциональность (т. е. переключатель командной строки, который перенаправляет вывод в STDOUT вместо окна).

Что касается p.getOutputStream(), это возвращает поток, который является «выходным» с ВАШЕЙ точки зрения, т.е. вы пишете в него для отправки данных в STDIN процесса. Ваше использование p.getInputStream() было бы правильным для случая, когда внешняя программа записывает в свой STDOUT.

person Jim Garrison    schedule 05.01.2010
comment
Ага ... так что, даже если окно, запущенное из командной строки, является другим окном терминала, запущенным этим другим процессом, его вывод не является STDOUT? Процесс либо печатает информацию в выходной файл, либо в окно. - person RCC; 05.01.2010
comment
Скорее всего, да. Как вы контролируете, пишет ли процесс в файл или во вторичное окно? Если это Linux, есть шанс, что он понимает - как выходной файл, означающий запись в STDOUT, и в этом случае вы можете использовать свой код. - person Jim Garrison; 06.01.2010
comment
К сожалению, это Windows. Сама программа принимает аргументы при вызове из командной строки с именем файла, в который нужно записать после ключевого слова output. Если программа должна писать в окно, пользователь просто опускает имя выходного файла при вызове программы. - person RCC; 06.01.2010
comment
Если программист явно не включил специальное ключевое слово для вывода в STDOUT, вам, вероятно, не повезло. Есть еще одна возможность, но она становится довольно причудливой — написать код для эмуляции хвостовой программы Unix, чтобы периодически опрашивать выходной файл для получения дополнительных данных. Я не уверен, возможно ли это с Java в Windows. - person Jim Garrison; 06.01.2010