8

Java を使用して外部プログラムの出力を取得しようとしていますが、できません。

それを表示するコードはありますが、変数に入れるコードはありません。

たとえば、sqlplus を使用してオラクル コードを実行し、「exec.sql に」 system/orcl@orcl : user/password/DB name

public static String test_script () {
        String RESULT="";
        String fileName = "@src\\exec.sql";
        String sqlPath = ".";
        String arg1="system/orcl@orcl";
        String sqlCmd = "sqlplus";


        String arg2   = fileName;
        try {
            String line;
            ProcessBuilder pb = new ProcessBuilder(sqlCmd, arg1, arg2);
            Map<String, String> env = pb.environment();
            env.put("VAR1", arg1);
            env.put("VAR2", arg2);
            pb.directory(new File(sqlPath));
            pb.redirectErrorStream(true);
            Process p = pb.start();
          BufferedReader bri = new BufferedReader
            (new InputStreamReader(p.getInputStream()));

          while ((line = bri.readLine()) != null) {

              RESULT+=line;

          }


          System.out.println("Done.");
        }
        catch (Exception err) {
          err.printStackTrace();
        }
 return RESULT;
    }
4

2 に答える 2

10

Process は新しいスレッドで実行されるため、while ループに入ったときに出力がないか、不完全な出力が利用できる可能性があります。

Process p = pb.start();  
// process runs in another thread parallel to this one

BufferedReader bri = new BufferedReader(new InputStreamReader(p.getInputStream()));

// bri may be empty or incomplete.
while ((line = bri.readLine()) != null) {
    RESULT+=line;
}

そのため、プロセスの出力を操作する前に、プロセスが完了するのを待つ必要があります。Process.waitFor()メソッドを使用して、プロセスが完了する機会が得られるまで現在のスレッドを一時停止してみてください。

Process p = pb.start();  
p.waitFor();  // wait for process to finish then continue.

BufferedReader bri = new BufferedReader(new InputStreamReader(p.getInputStream()));

while ((line = bri.readLine()) != null) {
    RESULT+=line;
}

これは単純なアプローチであり、プロセスを並行して実行しながら出力を処理することもできますが、プロセスのステータスを監視する必要があります。

于 2013-01-26T23:39:16.877 に答える
8

Apache Commons Execを使用すると、作業がずっと楽になります。基本的な使用方法については、チュートリアルを確認してください。executorオブジェクト (おそらく)を取得した後にコマンド ライン出力を読み取るには、任意のストリーム (つまり、インスタンスは 、 または)DefaultExecutorを作成し、次のようにします。OutputStreamFileOutputStreamSystem.out

executor.setStreamHandler(new PumpStreamHandler(yourOutputStream));
于 2013-01-26T23:00:23.607 に答える