如何在java中使用Runtime类执行多个Windows命令

时间:2012-06-24 18:42:00

标签: java runtime.exec

我正在尝试使用以下代码从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工作正常,它会执行并显示文件已成功复制。请有人能告诉我为什么会这样吗?

1 个答案:

答案 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);