Перенаправить Runtime.getRuntime(). Exec() с помощью System.setOut();
У меня есть программа Test.java:
import java.io.*;
public class Test {
public static void main(String[] args) throws Exception {
System.setOut(new PrintStream(new FileOutputStream("test.txt")));
System.out.println("HelloWorld1");
Runtime.getRuntime().exec("echo HelloWorld2");
}
}
Предполагается напечатать HelloWorld1 и HelloWorld2 в файле text.txt. Однако, когда я просматриваю файл, я вижу только HelloWorld1.
-
Где прошел HelloWorld2? Разве это исчезло в воздухе?
-
Предположим, что я хочу перенаправить HelloWorld2 на test.txt. Я не могу просто добавить " → test.txt" в команду, потому что я получу ошибку с уже открытым файлом. Итак, как мне это сделать?
Ответы
Ответ 1
Стандартный вывод Runtime.exec автоматически не отправляется на стандартный вывод вызывающего абонента.
Что-то вроде этого нужно сделать - получить доступ к стандартным выводам разветвленного процесса, прочитать его и затем записать его. Обратите внимание, что вывод из вильчатого процесса доступен для родителя с использованием метода getInputStream()
экземпляра процесса.
public static void main(String[] args) throws Exception {
System.setOut(new PrintStream(new FileOutputStream("test.txt")));
System.out.println("HelloWorld1");
try {
String line;
Process p = Runtime.getRuntime().exec( "echo HelloWorld2" );
BufferedReader in = new BufferedReader(
new InputStreamReader(p.getInputStream()) );
while ((line = in.readLine()) != null) {
System.out.println(line);
}
in.close();
}
catch (Exception e) {
// ...
}
}
Ответ 2
Так как JDK 1.5 есть java.lang.ProcessBuilder, который также обрабатывает потоки std и err. Это своего рода замена для java.lang.Runtime, и вы должны ее использовать.
Ответ 3
System.out НЕ является исходным текстом нового процесса, который вы породили, вызвав exec(). Если вы хотите увидеть "HelloWorld2", вы должны вернуть процесс, возвращенный из вызова exec(), затем вызвать метод getOutputStream().
Ответ 4
Более простой способ достижения цели:
ProcessBuilder builder = new ProcessBuilder("hostname");
Process process = builder.start();
Scanner in = new Scanner(process.getInputStream());
System.out.println(in.nextLine()); // or use iterator for multilined output