Наследование и перенаправление stdout - PullRequest
0 голосов
/ 21 ноября 2018

Я пытаюсь написать тест для класса, который использует ProcessBuilder.inheritIO, и я не могу заставить его работать.Я сократил код до самого ядра и нашел следующий пример, который, я думаю, должен записать весь вывод дочернего процесса в ByteArrayOutputStream, но не делает этого.

Среда: Java 9.0.4 onWindows 7

import java.io.*;

public class ProcessTest {
  public static void main(String[] args) throws Throwable {
    PrintStream original = System.out;
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    PrintStream ps = new PrintStream(baos);
    System.setOut(ps);

    System.out.println("BEGIN");
    Process process = new ProcessBuilder().command("where", "where")
                                          .inheritIO().start();
    process.waitFor();

    System.out.println("END");
    String output = new String(baos.toByteArray());
    original.println("output = " + output);
  }
}

Вывод:

C:\Windows\System32\where.exe
output = BEGIN
END

И когда я смотрю в отладчике, поток вывода не содержит путь к.

IЯ думаю, System.setOut не делает то, что я думаю, но я не уверен.Я обнаружил, что другие вопросы SO предполагают использование StreamGrabber, но я подумал, что это для Java 6 и более ранних версий, и унаследованное решение подойдет мне.Любая помощь будет оценена.Спасибо.

Редактировать Я понял, что звонить по номеру System.setOut() не совсем то, что я надеюсь.Это не меняет базовый файловый дескриптор 1.Если бы я делал это в C, я бы работал с файловыми дескрипторами низкого уровня.Но это не то, что делает setOut().Это просто изменение указателей.

1 Ответ

0 голосов
/ 21 ноября 2018

System.setOut изменяет стандартный вывод процесса Java.Нет никакой гарантии, что это повлияет на дочерние процессы.

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

Решение: не пытайтесь взломать System.out.Чтение из стандартного ввода процесса InputStream:

ProcessBuilder builder = new ProcessBuilder().command("where", "where").inheritIO();
builder.redirectOutput(ProcessBuilder.Redirect.PIPE);
Process process = builder.start();

String output;
try (InputStream processStdOut = process.getInputStream()) {
    output = new String(processStdOut.readAllBytes());
}

process.waitFor();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...