【问题标题】:ProcessBuilder Output hangs on readLineProcessBuilder 输出在 readLine 上挂起
【发布时间】:2014-07-02 15:41:09
【问题描述】:

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

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

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

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

这是我正在使用的代码,基于 (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();
        }
    }
}
}

谢谢!

【问题讨论】:

    标签: inputstream processbuilder freeze


    【解决方案1】:

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

     command - a string array containing the program and its arguments
    

    例如对于“ls -al”,您应该使用:

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

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

    问候 蒂洛

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-18
      • 2011-08-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多