ProcessBuilder输出在readLine上挂起

时间:2014-07-02 15:41:10

标签: inputstream processbuilder hang

我正在尝试使用ProcessBuilder运行一些命令,除了一个小细节之外,一切工作正常:在一种情况下,我只在任务完成运行时获得输出。我检查了程序,它挂在第一个readLine()上。我在单独的线程中运行它,我尝试将输入和错误流合并为" redirectErrorStream(true)"并将它们分开,不会改变上述行为。我也尝试过一个while循环,它只会在BufferedReader为ready()返回true之后执行第一个readLine()但是它没有工作(可能不是一个非常聪明的解决方案但是我正在尝试一切来理解发生了什么在...)

代码与一些可执行文件完美配合,在运行时提供输出,但在某些情况下挂起在第一个readline()...有人知道可能导致它的原因以及如何解决它? / p>

对我来说这有点奇怪,因为当我在命令提示符中执行相同的命令时,在程序运行时会显示输出。

这个问题似乎与我在其他主题中找到的问题相同,但我无法在其中任何一个问题中找到解决方案。

以下是我正在使用的代码,基于(http://thilosdevblog.wordpress.com/2011/11/21/proper-handling-of-the-processbuilder/):

List<String> command = new ArrayList<String>();
command.add(%COMMAND1)
command.add(%COMMAND2)
...
ProcessBuilderWrapper pbd = new ProcessBuilderWrapper(command);

ProcessBuilderWrapper:

public class ProcessBuilderWrapper {

public ProcessBuilderWrapper(File directory, List command) throws Exception {

    ProcessBuilder pb = new ProcessBuilder(command);
    if (directory != null) {
        pb.directory(directory);
    }
    pb.redirectErrorStream(true);
    Process process = pb.start();

    StreamBoozer seInfo = new StreamBoozer(process.getInputStream());

    seInfo.start();

}

public ProcessBuilderWrapper(List command) throws Exception {
    this(null, command);
}

}

StreamBoozer:

public class StreamBoozer extends Thread {

private InputStream in;

StreamBoozer(InputStream in) {
    this.in = in;
}

@Override
public void run() {
    BufferedReader br = null;
    br = new BufferedReader(new InputStreamReader(in));
    try {
        String line = null;
        while ((line = br.readLine()) != null) {  <<<<<<<<<<<<< It hangs here #####
            System.out.println(line);
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        try {
            br.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
}

谢谢!

1 个答案:

答案 0 :(得分:1)

我认为您误解了列表命令的构建。该列表不能用于超过1个命令。这意味着,您只能使用 ProcessBuilderWrapper 运行一个命令。 看看ProcessBuilder的Javadoc:

 command - a string array containing the program and its arguments

E.g。为了&#39; ls -al&#39;你应该使用:

 List command = new ArrayList();
 command.add("ls");
 command.add("-al");

如果您正在使用SteamBoozer-stuff 进程,则应使用waitFor SteamBoozer.join (查看上面提到的博客文章)。否则你可能遇到丑陋的计时问题!这可能会导致您上面描述的奇怪行为。

此致 蒂洛