Перенаправить вывод Runtime.getRuntime (). Exec () с помощью System.setOut (); - PullRequest
20 голосов
/ 20 января 2011

У меня есть программа 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.

  1. Куда делась HelloWorld2? Он растворился в воздухе? ​​

  2. Допустим, я хочу перенаправить HelloWorld2 и на test.txt. Я не могу просто добавить ">> test.txt" в команду, потому что я получу ошибку открытия файла. Так как мне это сделать?

Ответы [ 4 ]

37 голосов
/ 20 января 2011

Стандартный вывод Runtime.exec не отправляется автоматически на стандартный вывод вызывающей стороны.

Что-то вроде этого должно быть сделано - получить доступ к стандартному выводу разветвленного процесса, прочитать его, а затем записать. Обратите внимание, что выходные данные разветвленного процесса доступны родительскому элементу с помощью метода getInputStream() экземпляра Process.

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) {
       // ...
     }
}
5 голосов
/ 20 января 2011

Начиная с JDK 1.5 существует java.lang.ProcessBuilder, который также обрабатывает потоки std и err.Это своего рода замена java.lang.Runtime, и вы должны использовать его.

2 голосов
/ 20 января 2011

System.out НЕ является stdout из нового процесса, который вы создали, вызвав exec (). Если вы хотите увидеть «HelloWorld2», вы должны получить Process, возвращенный из вызова exec (), а затем вызвать getOutputStream () из этого.

0 голосов
/ 18 июня 2019

Более простой способ достижения цели:

    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
...