Ответ 1
Прежде всего, предпочтительный способ запуска внешних программ - ProcessBuilder
. Это даже упоминается в документах для Runtime
:
ProcessBuilder.start() теперь является предпочтительным способом запуска процесса с измененной средой.
В ProcessBuilder
у вас есть очень удобный метод redirectErrorStream
:
Устанавливает свойство redirectErrorStream этого процесса.
Если это свойство истинно, то любой вывод ошибки, созданный подпроцессами, впоследствии запущенный этим методом start() объекта, будет объединен со стандартным выходом, так что оба могут быть прочитаны с помощью Process. getInputStream(). Это упрощает корреляцию сообщений об ошибках с соответствующим выходом. Начальное значение ложно.
Полный пример того, как выводить как стандартную ошибку, так и стандартную:
import java.io.*;
public class Test {
public static void main(String... args) throws IOException {
ProcessBuilder pb =
new ProcessBuilder("java", "-cp", "yourClassPath", "HelloWorld");
pb.redirectErrorStream(true);
Process proc = pb.start();
Reader reader = new InputStreamReader(proc.getInputStream());
int ch;
while ((ch = reader.read()) != -1)
System.out.print((char) ch);
reader.close();
}
}
Ответ на ваше обновление: Нет, код с
while ((c = in1.read()) != -1 || (c = in2.read()) != -1)
не будет работать, поскольку read()
является методом блокировки, и у вас есть только один поток. Единственный вариант - использовать один поток для каждого потока ввода или (желательно) объединить два потока ввода в один, используя ProcessBuilder.redirectErrorStream
.