命令提示符中的Java issue命令

时间:2013-06-24 11:14:08

标签: java

我有以下类文件。这将启动命令提示符并打印响应。奇怪的是在第一次打印之后,即dir后续不打印。请指教。

import java.io.*;
public class JavaApplication14 {
static Process p;

public static void main(String[] args) {
    try {
        String line;

        p = Runtime.getRuntime().exec("cmd.exe");
        OutputStream stdin = p.getOutputStream();
        InputStream stderr = p.getErrorStream();
        InputStream stdout = p.getInputStream();

        BufferedReader reader = new BufferedReader(new InputStreamReader(stdout));
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(stdin));

        String input = "dir";
        input += "\n";
        writer.write(input);
        writer.flush();



        while ((line = reader.readLine()) != null) {
            System.out.println("Stdout: " + line);
        }
         input = "cd..";
        input += "\n";
        writer.write(input);
        writer.flush();
        input = "dir";
        input += "\n";
        writer.write(input);
        writer.close();

        while ((line = reader.readLine()) != null) {
            System.out.println("Stdout: " + line);
        }
    } catch (IOException ex) {
        Logger.getLogger(JavaApplication14.class.getName()).log(Level.SEVERE, null, ex);
    }
 }
 }

2 个答案:

答案 0 :(得分:4)

您的(第一个)while()循环永远不会终止:

while ((line = reader.readLine()) != null) {
    System.out.println("Stdout: " + line);
}
当流关闭时,

readLine()会返回null,但由于您的子流程仍在运行,因此流永远不会关闭。

要解决此问题,您可以将读取部分移动到单独的线程中(这需要额外的同步),或者更简单的解决方案是查看是否读取了特定的行内容,例如,如果打印了命令行提示符cmd.exe

while ( !(line = reader.readLine()).startsWith("C:\\") ) {
    System.out.println("Stdout: " + line);
}

这应该适用于您的特定用例,并且可能足以进行一些学习 - 对于实际应用程序,您可能希望查看Apache Commons Exec项目。

答案 1 :(得分:2)

您正尝试使用同步I / O操作从一个线程进行基本的异步工作。你的方法必将失败。

具体来说,readLine()会阻塞,直到有一整行要读取,或直到基础流关闭为止。

你需要编写更多代码,包括线程,才能使其工作。这是Java的一个难点。

您还可以使用ProcessBuilder,尤其是redirectOutput方法,使用参数值INHERIT,以使子流程继承主进程的stdout。在这种情况下,您将无法用Java分析子进程的输出。