Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/389.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java中分叉子进程的输出_Java_Process_Input - Fatal编程技术网

Java中分叉子进程的输出

Java中分叉子进程的输出,java,process,input,Java,Process,Input,我正在从Java程序在本机windows中执行cmd进程。我希望能够查看分叉流程的输入和输出。但是,我似乎无法从Java程序中写入任何内容 当我尝试在windows中的命令提示符上写入一组字符时,我有点希望它在屏幕上打印一些东西——任何东西。所以,如果我给它一些无意义的垃圾,那么它应该打印出它不理解这个命令 但是,在以下代码中将垃圾字符串写入子进程的OutputStream之后: Runtime runtime = Runtime.getRuntime(); Process process =

我正在从Java程序在本机windows中执行cmd进程。我希望能够查看分叉流程的输入和输出。但是,我似乎无法从Java程序中写入任何内容

当我尝试在windows中的命令提示符上写入一组字符时,我有点希望它在屏幕上打印一些东西——任何东西。所以,如果我给它一些无意义的垃圾,那么它应该打印出它不理解这个命令

但是,在以下代码中将垃圾字符串写入子进程的OutputStream之后:

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的写入方法?