1

我正在尝试使用一些简单的命令为 windows 命令提示符制作 Java GUI。我在额外输入方面遇到了一些问题。我可以运行“dir”命令,但是当我运行“del”命令时,我需要确认,但我似乎无法让它打印出确认消息。

public static void main(String args[])
{
    try {
        Process p = Runtime.getRuntime().exec("cmd /c dir");
        read(p);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

private static void read(Process p)
{
    try{
        BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
        String line = null;
        while((line=input.readLine()) != null) {
            System.out.println(line);
        }   
    }
    catch(IOException e1) { e1.printStackTrace(); }
}

输出:

 Volume in drive E has no label.
 Volume Serial Number is E9ED-7E32

 Directory of E:\Code\workspace\Project

04/11/2012  11:07 PM    <DIR>          .
04/11/2012  11:07 PM    <DIR>          ..
04/11/2012  09:53 PM               301 .classpath
04/11/2012  09:53 PM               383 .project
04/11/2012  09:53 PM    <DIR>          .settings
04/12/2012  12:09 AM    <DIR>          bin
04/12/2012  12:09 AM    <DIR>          src
04/11/2012  11:07 PM    <DIR>          test
               2 File(s)            684 bytes
               6 Dir(s)  429,106,937,856 bytes free

但是运行它会导致它挂在line=input.readLine()

public static void main(String args[])
{
    try {
        Process p = Runtime.getRuntime().exec("cmd /c del test");
        read(p);
        OutputStream oStream = p.getOutpuStream();
        BufferedWriter sWriter = new BufferedWriter(newOutputStreamWriter(oStream));
        sWriter.write("y");
        sWriter.newLine();
        oStream.close();
        read(p);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

如何防止这种挂起?我还担心没有正确发送确认“y”。我觉得应该读取输出并写入输入,但这是我在多个在线站点找到的方式。任何帮助,将不胜感激。

4

2 回答 2

3

当您启动 Java 进程时,您必须在错误流和输入流填满之前读取它们。在 Linux/OS X 下这没什么大不了的,但在 Windows 下,JVM 和子进程之间的缓冲区非常小,如果你不立即开始阅读,程序就会挂起。看起来代码正在为输入流而不是错误流执行此操作,因此如果来自 del 的确认出现在错误流上,那么这足以挂起进程。

Java 中有一种方法可以组合输出流和错误流。最简单的方法是在创建流程时使用ProcessBuilder.redirectErrorStream() 。

代码的另一个可能问题是使用readLine().如果子程序发送没有换行符的输出,那么父程序将不会收到它 - 因为对 readline 的调用将只是等待行尾(IIRC del 这样做) . 使用 BufferedReader 很好,但它确实应该一次读取一个字节/字符。如果代码在专用线程中执行此操作,它也会更加健壮,那么如果程序在您尝试传递输入时发送输出,它就不会挂起。

此外,del 上还有一个选项可以使其不提示确认。试试德尔/?从命令提示符。

祝你好运!

于 2012-04-12T04:55:59.757 回答
0

它所有的标准io(即stdin、stdout、stderr)操作都会通过三个流(Process.getOutputStream()、Process.getInputStream()、Process.getErrorStream())从原始进程重定向到父进程。您能否检查消息的确认是否是 ErrorStream 的一部分。此外,为了让您输入确认 y 以进行删除,您需要使用 inputStream。

于 2012-04-12T04:54:19.080 回答