Слив стандартной ошибки в Java - PullRequest
4 голосов
/ 15 сентября 2008

При запуске процесса из Java и stderr, и stdout могут блокировать вывод, если я не читаю из каналов. В настоящее время у меня есть поток, который активно читает из одного блока и из основного потока другого.

Есть ли простой способ объединить два потока или иным образом заставить подпроцесс продолжаться, не теряя данные в stderr?

Ответы [ 2 ]

4 голосов
/ 15 сентября 2008

Установите свойство redirectErrorStream в ProcessBuilder для отправки вывода stderr в stdout:

ProcessBuilder builder = new ProcessBuilder(command);
builder.redirectErrorStream(true);

Затем вы должны создать поток для обработки потока процесса, что-то вроде следующего:

Process p = builder.start();

InputHandler outHandler = new InputHandler(p.getInputStream());

Где InputHandler определяется как:

private static class InputHandler extends Thread {

    private final InputStream is;

    private final ByteArrayOutputStream os;

    public InputHandler(InputStream input) {
        this.is = input;
        this.os = new ByteArrayOutputStream();
    }

    public void run() {
        try {
            int c;
            while ((c = is.read()) != -1) {
                os.write(c);
            }
        } catch (Throwable t) {
            throw new IllegalStateException(t);
        }
    }

    public String getOutput() {
        try {
        os.flush();
        } catch (Throwable t) {
            throw new IllegalStateException(t);
        }
        return os.toString();
    }

}

В качестве альтернативы просто создайте два InputHandler для InputStream и ErrorStream. Знание того, что программа заблокируется, если вы не прочитаете их, - это 90% битвы:)

0 голосов
/ 15 сентября 2008

Просто есть два потока, одно чтение из stdout, одно из stderr?

...