我正在尝试使用一些简单的命令为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”没有正确发送。我觉得应该阅读输出并写入输入,但这是我在多个网站上找到的方式。任何帮助,将不胜感激。
答案 0 :(得分:3)
启动进程Java时,必须在填充之前读取错误和输入流。它在Linux / OS X下并不是一个大问题,但在Windows下,JVM和子进程之间的缓冲区非常小,如果你不立即开始阅读,程序将会挂起。看起来代码正在为输入流而不是错误流执行此操作,因此如果来自del的确认来自错误流,那么这将足以挂起该进程。
Java中有一种方法可以组合输出和错误流。最简单的方法是在创建流程时使用ProcessBuilder.redirectErrorStream()。
代码的另一个可能问题是如果子程序发送没有换行的输出,则使用readLine().
,然后父程序将不会收到它 - 因为对readline的调用只是等待结束线(IIRC del这样做)。它很适合使用BufferedReader,但它确实应该一次读取一个字节/ char。如果代码在专用线程中执行,它也会更强大,如果程序在您尝试传入输入时发送输出,它将不会挂起。
此外,del上有一个选项,使其无法提示确认。试试del /?从命令提示符。
祝你好运!答案 1 :(得分:0)
所有标准的io(即stdin,stdout,stderr)操作将通过三个流(Process.getOutputStream(),Process.getInputStream(),Process.getErrorStream())从原始进程重定向到父进程。 可以请检查消息的确认是否是ErrorStream的一部分。 您还可以输入确认y进行删除,您需要使用inputStream。