在 Java 中重定向标准输入和标准输出

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10407308/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 00:55:53  来源:igfitidea点击:

Redirect stdin and stdout in Java

javaprocessstdoutstdin

提问by Josh

I'm trying to redirect stdin and stdout of a subprocess in java, eventually i'm going to have the output go to a JTextArea or something.

我正在尝试在 java 中重定向子进程的 stdin 和 stdout,最终我要将输出转到 JTextArea 或其他东西。

Here is my current code,

这是我当前的代码,

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);

The output looks like this:

输出如下所示:

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

C:\(Current Directory)>

I'm expecting to see the "Hello World" string outputted. Maybe because the parent process isn't staying alive long enough?

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

I'd also like to be able to send and receive multiple commands.

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

回答by Hovercraft Full Of Eels

You've attempted to write to the output stream before you attempt to listen on the input stream, so it makes sense that you're seeing nothing. For this to succeed, you will need to use separate threads for your two streams.

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

i.e.,

IE,

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();
   }
}

And you really shouldn't ignore the error stream either but instead should gobble it, since ignoring it will sometimes fry your process as it may run out of buffer space.

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

回答by óscar López

Nowadays Runtime.getRuntime().exec()is deprecated (for all practical purposes). Better use the ProcessBuilderclass; in particular, its start()method will return a Processobject with methods for accessing the stdin and stdout streams, which can be redirected wherever you need them. Take a look at this postfor further details.

如今Runtime.getRuntime().exec()已被弃用(出于所有实际目的)。最好使用ProcessBuilder类;特别是,它的start()方法将返回一个Process对象,其中包含用于访问 stdin 和 stdout 流的方法,这些流可以重定向到您需要的任何地方。看看这篇文章了解更多详情。