5

外部の「javamyprog<input.txt>output.txt」コマンドを実行するJavaプログラムを作成したいと思います。最終的な目標は、このコマンドを2つの異なるプログラムで実行し、それぞれの出力ファイルからの出力の類似性を比較することです。

ProcessBuilderを使用して外部プログラムを実行することに関するほぼすべての関連記事と、その外部プログラムでのユーザー入力の処理に関するいくつかのエントリを読んだと思いますが、それでも動作させることができません。私が読んだことから、最善のアプローチは、上記の正確なコマンドを実行するのではなく、代わりにinput.txtファイルを読み取り、それをバイトごとにProcessオブジェクトにフィードしてから、出力を収集して出力に書き込むことだと思います。 .txt ...私は他のオプションを100%受け入れています。

私は自分の読みに基づいて以下のコードをまとめました。input.txtからmyprogに入力を正しくフィードしているように見えますが、外部プログラムの出力をコンソールに出力して確認しようとすると、myprogで(驚きの)ユーザー入力が期待されるポイントでプログラムがハングします。

redirectErrorStream(true)行がある場合とない場合で同じ問題が発生します。

プログラムの出力を比較する人々とソースコードを共有する予定であり、彼らは主にJavaに精通しているだけなので、これをJavaで使用したいと思っています。

import java.io.*;
import java.util.*;

public class test7 {

    public static void main(String args[]) {

        try {
            // WANT: "java myprog < input.txt > output.txt"
            String inputFile = "input.txt";
            String outputFile = "output.txt";

            ProcessBuilder pb = new ProcessBuilder("java","myprog");
            pb.redirectErrorStream(true); // merge stdout, stderr of process
            Process p = pb.start();

            // write input to the running program
            OutputStream pos = p.getOutputStream();
            InputStream fis = new FileInputStream(inputFile);
            int read = 0;
            while ( (read = fis.read()) != -1) {
                pos.write(read);
            }
            fis.close();

            // get output of running program
            InputStreamReader isr = new  InputStreamReader(p.getInputStream());
            BufferedReader br = new BufferedReader(isr);

            // HANGS HERE WHEN USER INPUT REQUIRED
            String lineRead;
            while ((lineRead = br.readLine()) != null) {
                System.out.println(lineRead);
            }

        }
        catch (IOException e) {
            e.printStackTrace(); 
        }
    } // end main

}

myprog.javaの内容は次のとおりです。

import java.io.*;

public class myprog {

    public static void main(String args[]) throws IOException {

        System.out.println("Hello world!");
        System.out.println("Enter something:");

        BufferedReader cin = new BufferedReader(new InputStreamReader(System.in));

        // the readLine() command causes ProcessBuilder to hang
        cin.readLine();
    }   
}

そしてinput.txtファイルはただです

p

output.txtファイルは次のようになります

Hello world!
Enter something:
4

3 に答える 3

4

あなたの問題の一部は、入力の読み取りと出力の書き込みに別々のスレッドを使用していないことに関係しているのだろうか。例えば:

   public static void main(String args[]) {

      try {
         // WANT: "java myprog < input.txt > output.txt"
         String inputFile = "input.txt";
         String outputFile = "output.txt";

         // my ProcessBuilder Strings will be different from yours
         ProcessBuilder pb = new ProcessBuilder("java", "-cp", ".;bin;",
               "yr12.m04.a.MyProg");
         pb.redirectErrorStream(true); 
         Process p = pb.start();

         final OutputStream pos = p.getOutputStream();
         final PrintWriter pw = new PrintWriter(pos);
         final InputStream fis = new FileInputStream(inputFile);
         final BufferedReader fileBr = new BufferedReader(new InputStreamReader(fis));

         InputStreamReader isr = new InputStreamReader(p.getInputStream());
         final BufferedReader br = new BufferedReader(isr);

         new Thread(new Runnable() {
            public void run() {
               String lineRead;
               try {
                  while ((lineRead = br.readLine()) != null) {
                     System.out.println(lineRead);
                  }
               } catch (IOException e) {
                  e.printStackTrace();
               } finally {
                  if (br != null) {
                     try {
                        br.close();
                     } catch (IOException e) {
                        e.printStackTrace();
                     }
                  }
               }
            }
         }).start();

         new Thread(new Runnable() {
            public void run() {
               try {
                  String lineRead;
                  while ((lineRead = fileBr.readLine()) != null) {
                     pw.println(lineRead);
                  }
               } catch (IOException e) {
                  e.printStackTrace();
               } finally {
                  if (pw != null) {
                     pw.close();
                  }
                  if (fileBr != null) {
                     try {
                        fileBr.close();
                     } catch (IOException e) {
                        e.printStackTrace();
                     }
                  }
               }
            }
         }).start();

      } catch (IOException e) {
         e.printStackTrace();
      }
   } // end main
于 2012-04-18T16:39:40.450 に答える
0

「myprog」の jar を含めて、main() メソッドを自分で呼び出すことができます。さらに、myprog がドメイン内にある場合は、main メソッドを完全に取り除くことができます。

于 2012-04-18T16:07:07.287 に答える
0

代わりに Runtime.getRuntime().exec() を使用することを考えましたか?

Process proc = Runtime.getRuntime().exec("java myprog "+inputFile+" "+outputFile);
于 2012-04-18T14:50:19.210 に答える