2012-04-18 31 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