如何从Java读取命令行输出(通过Runtime.getRuntime()。exec(...))

时间:2010-09-18 15:34:52

标签: java command-line console runtime exec

我正在尝试在Swing应用程序中提供有关符号链接存在的一些信息。 GUI具有JTextArea resultTextAreaJTextField statusField。这是Dialog类中的代码:

public void checkForSymLinks(File... dirs) {
    for (File dir : dirs) {
        try {
            Process p = Runtime.getRuntime().exec("find -type l", null, dir);
            BufferedReader in = new BufferedReader(
                    new InputStreamReader(p.getInputStream()));
            String line = null;
            while ((line = in.readLine()) != null) {
                resultTextArea.append(line);
            }
        } catch (IOException ex) {
            Logger.getLogger(SymbolicLinkSearchResultDialog.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    statusField.setText("SymLinks found! // FIXME");
}

我尝试并将Process p = Runtime.getRuntime().exec("find -type l", null, dir);替换为:

ProcessBuilder pb = new ProcessBuilder("find -type l");
pb.directory(dir).redirectErrorStream(true);
Process p = pb.start(); 

但这没有帮助。

问题在于它既不会向resultTextArea写入任何内容,也不会到达代码以在最后一行设置statusField。它似乎挂在某个地方,尽管GUI保持响应。

我在关闭对话框时得到以下stacktrace:

java.io.IOException: Cannot run program "find -type l" (in directory "/home/johndoe/Desktop/test"): error=2, No such file or directory
    at java.lang.ProcessBuilder.start(ProcessBuilder.java:1024)

我已经尝试了/usr/bin/find type -l等许多其他事情...... 我做错了什么想法?

PS:Operationg系统是Linux。

奇怪的是:

def symLinkCheck(dirs: Array[File]) = {                              
  dirs.foreach{ dir =>                                                        
    val p = Runtime.getRuntime().exec("find -type l", null, dir)                    
    val in = new BufferedReader(new InputStreamReader(p.getInputStream)) 
    var line: String = null
    while({line = in.readLine; line} != null){
      println(line)
    }
  }
}

我在Scala中尝试了这个代码,它没有问题。如果我的问题可能与Swing有关,我真的不确定了吗?

编辑:问题肯定与Swing有关。

如果我在theGUI.setVisible(true)之前调用该方法,那么它可以正常工作,但之后就没有了。

我已经尝试了SingUtilities.invokeLater,但这没有帮助。

3 个答案:

答案 0 :(得分:1)

您没有说明您正在使用哪种操作系统。假设您的find命令语法正确(在Mac OSX上不正确),我认为您应该:

  1. 同时使用stdout和stderr。您需要同时执行 以避免阻止行为。有关详细信息,请参阅this SO answer
  2. 通过Process.waitFor()
  3. 从衍生过程中收集退出代码

答案 1 :(得分:0)

通过比较File.getCanonicalPath()File.getAbsolutePath()的结果,您可以在Java中执行此操作,而不是运行Unix命令来查找符号链接。

this问题中的更多详细信息。

答案 2 :(得分:0)

我发现问题:在GUI被构造之后,没有从事件调度线程调用该方法。