1

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

4

1 回答 1

4

您需要清理第一个进程的流,否则程序将阻塞,因为“wget”进程产生的输出在您当前的实现中永远不会读取。您需要整理出第一个流程的输出和错误流。查看关于 SO 上 java-runtime-exec 的另一个问题的答案。

下面的代码可供参考,但依赖于 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);
于 2012-06-24T18:50:51.083 回答