web-dev-qa-db-ja.com

System.setOut();を使用して、Runtime.getRuntime()。exec()の出力をリダイレクトします。

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」をコマンドに追加することはできません。ファイルを開くときにエラーが発生するためです。では、どうすればよいですか?

23
Leo Izen

Runtime.execの標準出力は、呼び出し元の標準出力に自動的には送信されません。

このようなことを行うと、フォークされたプロセスの標準出力にアクセスし、それを読み取ってから書き出すことができます。フォークされたプロセスからの出力は、Processインスタンスの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) {
       // ...
     }
}
40
martin clayton

JDK 1.5以降、stdおよびerrストリームも処理するJava.lang.ProcessBuilderがあります。これは、Java.lang.Runtimeの置き換えのようなものであり、使用する必要があります。

5
initialZero

System.outは、exec()を呼び出して作成した新しいプロセスのstdoutではありません。 「HelloWorld2」を表示したい場合は、exec()呼び出しから返されたプロセスを取得し、それからgetOutputStream()を呼び出す必要があります。

2
rfeak

目的を達成するためのより簡単な方法:

    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
0
fg78nc