【问题标题】:Redirect stdin and stdout in Java在 Java 中重定向标准输入和标准输出
【发布时间】:2012-05-11 13:07:59
【问题描述】:

我正在尝试重定向 java 中子进程的标准输入和标准输出,最终我会让输出转到 JTextArea 或其他东西。

这是我当前的代码,

Process cmd = Runtime.getRuntime().exec("cmd.exe");

cmd.getOutputStream().write("echo Hello World".getBytes());
cmd.getOutputStream().flush();

byte[] buffer = new byte[1024];
cmd.getInputStream().read(buffer);
String s = new String(buffer);

System.out.println(s);

输出如下所示:

Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.

C:\(Current Directory)>

我期待看到“Hello World”字符串的输出。 可能是因为父进程的存活时间不够长?

我还希望能够发送和接收多个命令。

【问题讨论】:

    标签: java process stdout stdin


    【解决方案1】:

    您已尝试在尝试侦听输入流之前写入输出流,因此您什么也没看到是有道理的。为了成功,您需要为两个流使用单独的线程。

    即,

    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.OutputStream;
    import java.io.PrintWriter;
    import java.util.Scanner;
    
    public class Foo {
       public static void main(String[] args) throws IOException {
          Process cmd = Runtime.getRuntime().exec("cmd.exe");
    
          final InputStream inStream = cmd.getInputStream();
          new Thread(new Runnable() {
             public void run() {
                InputStreamReader reader = new InputStreamReader(inStream);
                Scanner scan = new Scanner(reader);
                while (scan.hasNextLine()) {
                   System.out.println(scan.nextLine());
                }
             }
          }).start();
    
          OutputStream outStream = cmd.getOutputStream();
          PrintWriter pWriter = new PrintWriter(outStream);
          pWriter.println("echo Hello World");
          pWriter.flush();
          pWriter.close();
       }
    }
    

    你真的不应该忽略错误流,而是应该吞噬它,因为忽略它有时会烧毁你的进程,因为它可能会耗尽缓冲区空间。

    【讨论】:

    • @Hovevercraft:您说他是“您在尝试侦听输入流之前尝试写入输出流,因此您什么也没看到是有道理的”。我不明白为什么在编写命令之后阅读 会导致短读。其实你说“什么都没看到”,但至少他看到了cmd.exe的banner和提示。我的印象是,如果他再读一遍,他就会看到剩下的部分。我错过了什么?
    【解决方案2】:

    现在 Runtime.getRuntime().exec() 已被弃用(出于所有实际目的)。更好地使用ProcessBuilder 类;特别是,它的start() 方法将返回一个Process 对象,其中包含用于访问标准输入和标准输出流的方法,可以将它们重定向到您需要的任何地方。请查看post 了解更多详情。

    【讨论】:

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