我正在尝试使用以下代码从Java执行Windows命令,
Process p=Runtime.getRuntime().exec("wget www.anyurl.com/index.html);
并且它有效但当我尝试执行另一个命令时,如下所示,
Process p1=Runtime.getRuntime().exec("pscp -pw sysadmin c:/mydirectory/mypage.html mahesh@vmstni01:/home/usr");
它似乎不起作用。如果我注释掉第一个流程行(即流程p),那么流程p1工作正常,它会执行并显示文件已成功复制。请有人能告诉我为什么会这样吗?
答案 0 :(得分:4)
您需要清理第一个进程的流,否则程序将阻塞,因为“wget”进程会生成在当前实现中从未读取的输出。您需要整理第一个进程的输出和错误流。看看答案,例如another question about java-runtime-exec on SO
下面的代码可供参考,但依赖于wget生成输出到stderr和pscp到stdout的事实。如果有任何内容输出到另一个相应的流,只要输出适合Java程序的缓冲区(请注意这些缓冲区大小往往因平台而异),代码就会工作,同时它会清空第一个流。如果缓冲区已满,则执行该命令只会阻塞。您应该为stout和stderr创建一个单独的线程,以读取进程的相应流。
import java.io.BufferedReader;
import java.io.InputStreamReader;
...
Process p=Runtime.getRuntime().exec("wget http://www.duckduckgo.com/");
BufferedReader perr=new BufferedReader(new InputStreamReader(p.getErrorStream()));
BufferedReader pout=new BufferedReader(new InputStreamReader(p.getInputStream()));
// We read stderror first from wget, because it spits the progress information into stderr
for (String s=perr.readLine(); s!=null; s=perr.readLine())
{
System.out.println("Stderr from p: "+s);
}
for (String s=pout.readLine(); s!=null; s=pout.readLine())
{
System.out.println("Stdout from p: "+s);
}
// if you need to check whether the command actually returned normally
int returnCode = p.waitFor();
perr.close();
pout.close();
System.out.println("Returned from p with exit code "+returnCode);
p=Runtime.getRuntime().exec("pscp -pw dontuseplainpwusesshkeys index.html user@10.0.0.11:");
perr=new BufferedReader(new InputStreamReader(p.getErrorStream()));
pout=new BufferedReader(new InputStreamReader(p.getInputStream()));
// We read stdout of pscp first because pscp spits stuff into stdout.
// The process will block if the buffer gets full and does not get emptied.
for (String s=pout.readLine(); s!=null; s=pout.readLine())
{
System.out.println("Stdout from p: "+s);
}
for (String s=perr.readLine(); s!=null; s=perr.readLine())
{
System.out.println("Stderr from p: "+s);
}
int returnCode1 = p.waitFor();
perr.close();
pout.close();
System.out.println("Process exited with return code "+returnCode1);