Я бы хотел добавить одну вещь к счастливому ответу Гарри .
Иногда первая запись в поток происходит перед добавлением прослушивателя потока. Тогда streamAppended
на слушателе никогда не вызывается для этих записей, поэтому вывод теряется.
См., Например, эту ошибку . Я думаю, что у счастливого времени у Гарри может быть эта проблема. Я сам зарегистрировал свой потоковый слушатель в ILaunchListener.launchChanged
, и это случилось 4/5 раз.
Если кто-то хочет быть уверенным, что все выходные данные получены из потока, то метод IStreamMonitor.getContents
можно использовать для извлечения выходных данных, которые произошли до добавления слушателя.
Ниже приведена попытка использования вспомогательного метода, который обрабатывает это. Он основан на коде в ProcessConsole
.
/**
* Adds listener to monitor, and calls listener with any content monitor already has.
* NOTE: This methods synchronises on monitor while listener is called. Listener may
* not wait on any thread that waits for monitors monitor, what would result in dead-lock.
*/
public static void addAndNotifyStreamListener(IStreamMonitor monitor, IStreamListener listener) {
// Synchronise on monitor to prevent writes to stream while we are adding listener.
// It's weird to synchronise on monitor because that's a shared object, but that's
// what ProcessConsole does.
synchronized (monitor) {
String contents = monitor.getContents();
if (!contents.isEmpty()) {
// Call to unknown code while synchronising on monitor. This is dead-lock prone!
// Listener must not wait for other threads that are waiting in line to
// synchronise on monitor.
listener.streamAppended(contents, monitor);
}
monitor.addListener(listener);
}
}
PS: В ProcessConsole.java
происходят странные вещи. Почему буферизация содержимого переключается из конструктора ProcessConsole.StreamListener
?! Если ProcessConsole.StreamListener
работает до этого, возможно, это решение не работает.