【问题标题】:Running external program with redirected stdin and stdout from Java使用来自 Java 的重定向标准输入和标准输出运行外部程序
【发布时间】:2012-07-05 09:00:09
【问题描述】:

我正在尝试从 Java 程序运行外部程序,但遇到了问题。基本上我想做的是:

 Runtime.getRuntime().exec("./extprogram <fileIn >fileOut");

但是我发现这不起作用 - Java 明显需要使用 Process 来处理输入和输出流以及其他我没有经验的东西。

我查看了互联网上的许多示例(其中许多来自 SO),但似乎没有一个简单的标准方法可以做到这一点,对于那些不完全了解什么的人来说继续进行,可能会非常令人沮丧。

我在尝试根据其他人的代码示例构建自己的代码时也遇到了麻烦,因为通常大多数其他人似乎 1. 对重定向 stdin 不感兴趣,并且 2. 不一定重定向 @ 987654324@ 到文件,而不是System.out

那么,任何人都可以向我指出任何用于调用外部程序和重定向stdinstdout 的简单代码模板的方向吗?谢谢。

【问题讨论】:

    标签: java exec stdout stdin


    【解决方案1】:

    你可以试试这样的:

    ProcessBuilder pb = new ProcessBuilder();
    pb.redirectInput(new FileInputStream(new File(infile));
    pb.redirectOutput(new FileOutputStream(new File(outfile));
    pb.command(cmd);
    pb.start().waitFor();
    

    【讨论】:

    【解决方案2】:

    如果你必须使用Process,那么这样的东西应该可以工作:

    public static void pipeStream(InputStream input, OutputStream output)
       throws IOException
    {
       byte buffer[] = new byte[1024];
       int numRead = 0;
    
       do
       {
          numRead = input.read(buffer);
          output.write(buffer, 0, numRead);
       } while (input.available() > 0);
    
       output.flush();
    }
    
    public static void main(String[] argv)
    {
       FileInputStream fileIn = null;
       FileOutputStream fileOut = null;
    
       OutputStream procIn = null;
       InputStream procOut = null;
    
       try
       {
          fileIn = new FileInputStream("test.txt");
          fileOut = new FileOutputStream("testOut.txt");
    
          Process process = Runtime.getRuntime().exec ("/bin/cat");
          procIn = process.getOutputStream();
          procOut = process.getInputStream();
    
          pipeStream(fileIn, procIn);
          pipeStream(procOut, fileOut);
       }
       catch (IOException ioe)
       {
          System.out.println(ioe);
       }
    }
    

    注意:

    • 请务必close 直播
    • 将此更改为使用缓冲流,我认为原始的Input/OutputStreams 实现可能一次复制一个字节。
    • 进程的处理可能会根据您的具体进程而改变:cat 是最简单的管道 I/O 示例。

    【讨论】:

    • 这对我有用!太感谢了。我在这段代码中遇到的最后一个问题是——当程序完成时,文件是空的(它们确实已经有数据——程序正在使用它)。为什么会这样?
    • MattS:我稍微更新了代码,早期的流处理有几个问题(我没有充分考虑流处理)。这些变化可能会有所帮助。还添加了一些注释。
    • @pb1q 太好了,我稍后会看一下。使用以前的代码,我确实记得关闭输入/输出流,但我忘记关闭进程的错误流,这是因为一次打开太多文件而导致崩溃。再次感谢。
    【解决方案3】:

    您尝试过 System.setIn 和 System.setOut 吗?自 JDK 1.0 以来一直存在。

    public class MyClass
    {
        System.setIn( new FileInputStream( "fileIn.txt" ) );
        int oneByte = (char) System.in.read();
        ...
    
        System.setOut( new FileOutputStream( "fileOut.txt" ) );
        ...
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-05-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多