2012-04-18 51 views
5

我想編寫一個運行外部「java myprog < input.txt> output.txt」命令的Java程序。最終目標是在兩個不同的程序上運行此命令,並比較它們各自輸出文件的輸出相似性。運行外部「Java myprog < input.txt > output.txt」的Java程序

我想我已經讀了這篇關於使用的ProcessBuilder運行外部程序每一個相關的文章,以及關於外部程序處理用戶輸入的幾個條目,但我仍然無法得到的東西的工作。從我讀過的內容來看,我認爲最好的方法是不運行上面的確切命令,而是讀取input.txt文件,並逐字節地將它送入Process對象,然後收集輸出並將其寫入輸出.txt ...我對其他選項100%開放。

我下面的代碼放在一起基於我的讀數。它似乎正確地將來自input.txt的輸入饋送到myprog中,但是當我嘗試將外部程序的輸出打印到控制檯進行驗證時,程序在myprog中預期的(驚訝的)用戶輸入處掛起。

我得到同樣的問題,有和沒有redirectErrorStream(真)線。

我真的希望這是在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: 
+0

你是什麼意思的用戶輸入要求?你能不能展示你的myprog或至少它最相關的部分?另外,如果您想在此獲得更好的幫助,請遵循Java命名約定。您使用非標準的命名(包括不使用大寫的第一個字母名稱)會使您的代碼混淆。 – 2012-04-18 14:49:45

+2

我前一段時間回答這個.. http://stackoverflow.com/questions/3062305/executing-shell-commands-from-java/3062874#3062874 – dsmith 2012-04-18 14:51:40

+0

@HovercraftFullOfEels:我添加myprog.java來描述的內容。我很抱歉沒有大寫類名。 – missthang 2012-04-18 15:44:15

回答

0

你有沒有想過使用Runtime.getRuntime ().exec()而不是?

Process proc = Runtime.getRuntime().exec("java myprog "+inputFile+" "+outputFile); 
+0

這比使用ProcessBuilder沒有任何優勢。 – 2012-04-18 14:52:50

+0

仍然以相同的方式掛起。 – missthang 2012-04-18 15:36:11

+0

在我的例子中,我離開了「<" and ">」,你添加了這些嗎? @Hovercraft ... 1行代碼vs 10在我的書中總是有優勢的,但是對於他們自己。 – user282172 2012-04-18 15:43:55

0

您可以包含'myprog'的jar並自己調用main()方法。更有甚者,如果myprog在你的域中,你可以完全擺脫主要方法。

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

就是這樣!與java命令的類路徑切換完美協作。非常感謝!!!!! – missthang 2012-04-18 17:08:06

+0

@missthang:很高興你有它的工作。 – 2012-04-18 17:12:57