Java中分叉子进程的输出
我正在从Java程序在本机windows中执行cmd进程。我希望能够查看分叉流程的输入和输出。但是,我似乎无法从Java程序中写入任何内容 当我尝试在windows中的命令提示符上写入一组字符时,我有点希望它在屏幕上打印一些东西——任何东西。所以,如果我给它一些无意义的垃圾,那么它应该打印出它不理解这个命令 但是,在以下代码中将垃圾字符串写入子进程的OutputStream之后:Java中分叉子进程的输出,java,process,input,Java,Process,Input,我正在从Java程序在本机windows中执行cmd进程。我希望能够查看分叉流程的输入和输出。但是,我似乎无法从Java程序中写入任何内容 当我尝试在windows中的命令提示符上写入一组字符时,我有点希望它在屏幕上打印一些东西——任何东西。所以,如果我给它一些无意义的垃圾,那么它应该打印出它不理解这个命令 但是,在以下代码中将垃圾字符串写入子进程的OutputStream之后: Runtime runtime = Runtime.getRuntime(); Process process =
Runtime runtime = Runtime.getRuntime();
Process process = runtime.exec("cmd");
BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
PrintWriter out = new PrintWriter(process.getOutputStream());
String line = null;
out.println("My Garbage String");
while((line = readLine()) != null)
System.out.println(line);
当((line=readLine())!=null)时,程序会在显示的位置停止
因此,父进程显然是阻塞的,直到子进程获得一些输入并取消阻塞并将该输入发送给父进程。但是,当我在PrintWriter
的println()方法中写入任何内容时,我会给子进程一些输入,不是吗
更新
现在,因为有人给了我一些答案,我决定澄清我的问题是什么。我可以很好地从命令提示符读取输出。事实上,当我第一次运行它时,我得到的输出与您在命令提示符中键入“cmd”时通常得到的输出相同
例如,以下面的代码示例为例:
Process process = Runtime.getRuntime().exec("cmd");
BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
PrintWriter out = new PrintWriter(process.getOutputStream());
String line = null;
do
{
line = in.readLine();
System.out.println(line);
}while(line!=null)
代码的输出将如下所示:
Microsoft Windows XP[版本5.1.2600](C)版权所有1985-2001
微软公司
如您所见,命令提示符为我的父进程提供了一些输出。但是,在我的IDE中以调试模式运行它时,我发现它只是在line=in.readLine()处停止代码>行。因此,子进程会阻塞,因为没有其他要打印的内容
因此,当我尝试使用它的OutputStream
属性给它一些输入时,它似乎没有响应。相反,程序在line=in.readLine()处阻塞代码>
作为对一张海报建议的回应,您提到的文章(当Runtime.exec()不支持时)只讨论了从OutputStream
和ErrorStream
属性获取输出。它没有提到除了运行Runtime.exec(args)
时以数组形式给出的初始执行参数之外,我如何为它提供任何类型的输入
为了模拟我最初想要做的事情(例如,给它随机垃圾,让它打印它不理解命令),我只需键入Runtime.getRumtime().exec(“cmd/c随机垃圾”);
并运行它。但是,这不是我想做的。我想在命令提示符开始执行后与它通信
最终,我希望能够与其他程序进行交互,这些程序通常要求您在从Java程序执行后与它们进行交互。然而,如果我唯一能告诉它该做什么的时间是在指定其执行参数时,那么我将无法以我希望的方式使用Java与单独的进程进行交互
如果有人知道如何做到这一点,请告诉我。谢谢。StreamGobbler
s是谷歌搜索他们的方式。他们从新的线程开始,正在阅读输出
这是一篇很好的文章,介绍了如何实现它们。Java程序控制process.getOutputStream()的输入。如果要向程序发送数据,需要从Java发送数据。这里有一个完整的示例。请注意,这将通过输出流运行dir命令
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
class StreamGobbler extends Thread {
InputStream is;
String type;
StreamGobbler(InputStream is, String type) {
this.is = is;
this.type = type;
}
public void run() {
try {
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line = null;
while ((line = br.readLine()) != null)
System.out.println(type + ">" + line);
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
public class GoodWindowsExec {
public static void main(String args[]) {
try {
String osName = System.getProperty("os.name");
String[] cmd = new String[1];
cmd[0] = "cmd.exe";
Runtime rt = Runtime.getRuntime();
Process proc = rt.exec(cmd);
proc.getOutputStream().write("dir \n".getBytes());
proc.getOutputStream().flush();
// any error message?
StreamGobbler errorGobbler = new StreamGobbler(
proc.getErrorStream(), "ERROR");
// any output?
StreamGobbler outputGobbler = new StreamGobbler(
proc.getInputStream(), "OUTPUT");
// kick them off
errorGobbler.start();
outputGobbler.start();
// any error???
int exitVal = proc.waitFor();
System.out.println("ExitValue: " + exitVal);
} catch (Throwable t) {
t.printStackTrace();
}
}
}
你把事情弄糊涂了。
首先,当前的描述是混乱的,你应该重写它
第二,按照法莫的回答中提供的方法执行StreamGobbler
你期望从中得到什么
out.println("My Garbage String");
while((line = readLine()) != null)
...
?
它完全按照它所说的做。将字符串发送到外部进程的输入流,然后在同一输入流中等待任何字符串到达。您之前发送的字符串当然早就消失了。“当((line=readLine())!=null)时,程序停止在它所说的位置。”
答案可能在另一期中(来自卢克·伍德沃德的答案):
..循环时((line=readLine())!=null)
仅当读卡器读取流程的标准时退出
输出,返回文件结尾。这仅在进程退出时发生。
如果当前没有,它将不会返回文件的结尾
进程将有更多的输出。相反,它将等待下一行
进程的输出,直到有了下一行才返回
尝试使用一个线程将命令写入process.getOutputStream(),并使用第二个线程读取process.getInputStream().我不明白你在说什么。这不正是我在做的吗???你读了我的示例代码吗?我又读了一遍代码,看不出你在写什么。你能给我指出来吗?读输出对我来说一点问题都没有。我的问题是输入。否决票,因为这不是“Java子进程”的问题正如我在回答中所描述的,我相当于一个基本的编程理解问题。你应该为你的问题选择一个答案,因为他没有刷新流,所以没有发送。我不确定你是否必须刷新它,但它不会改变任何东西。他使用的代码没有意义。在这里,你使用OutputStr来编写命令提示符eam的write方法,并将带有行终止字符的命令作为一组字节写入该方法。我一直在使用OutputStream的println方法,在没有行终止字符的情况下严格地作为字符串写入字符串。这一直是我的问题吗???我唯一可以写入外部程序的方法是o将一系列字节写入OutputStream的写入方法?