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

如何从Java读取命令行输出(通过Runtime.getRuntime().exec(…),java,command-line,console,runtime,exec,Java,Command Line,Console,Runtime,Exec,我试图在Swing应用程序中提供一些关于符号链接存在的信息。 GUI有一个JTextArea resultTextArea和一个JTextField statusField。这是Dialog类中的代码: public void checkForSymLinks(File... dirs) { for (File dir : dirs) { try { Process p = Runtime.getRuntime().exec("find -type

我试图在Swing应用程序中提供一些关于符号链接存在的信息。 GUI有一个
JTextArea resultTextArea
和一个
JTextField 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");
}
ProcessBuilder pb = new ProcessBuilder("find -type l");
pb.directory(dir).redirectErrorStream(true);
Process p = pb.start(); 
我尝试并替换了
processp=Runtime.getRuntime().exec(“find-typel”,null,dir)作者:

ProcessBuilder pb = new ProcessBuilder("find -type l");
pb.directory(dir).redirectErrorStream(true);
Process p = pb.start(); 
但这没有帮助

ProcessBuilder pb = new ProcessBuilder("find -type l");
pb.directory(dir).redirectErrorStream(true);
Process p = pb.start(); 
问题是它不知何故既不向
resultTextArea
写入任何内容,也不到达代码以设置最后一行中的statusField。它似乎挂在某个地方,尽管GUI保持响应

ProcessBuilder pb = new ProcessBuilder("find -type l");
pb.directory(dir).redirectErrorStream(true);
Process p = pb.start(); 
关闭对话框后,我得到以下堆栈跟踪:

ProcessBuilder pb = new ProcessBuilder("find -type l");
pb.directory(dir).redirectErrorStream(true);
Process p = pb.start(); 
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
和其他很多东西。。。 知道我做错了什么吗

ProcessBuilder pb = new ProcessBuilder("find -type l");
pb.directory(dir).redirectErrorStream(true);
Process p = pb.start(); 
PS:操作系统是Linux

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

ProcessBuilder pb = new ProcessBuilder("find -type l");
pb.directory(dir).redirectErrorStream(true);
Process p = pb.start(); 
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中尝试了这段代码,它毫无问题地工作了。我不确定我的问题是否与挥杆有关

ProcessBuilder pb = new ProcessBuilder("find -type l");
pb.directory(dir).redirectErrorStream(true);
Process p = pb.start(); 
编辑:问题肯定与Swing有关。

ProcessBuilder pb = new ProcessBuilder("find -type l");
pb.directory(dir).redirectErrorStream(true);
Process p = pb.start(); 
如果我在gui.setVisible(true)
之前调用这个方法,它会工作,但在那之后就不会了

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

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

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

ProcessBuilder pb = new ProcessBuilder("find -type l");
pb.directory(dir).redirectErrorStream(true);
Process p = pb.start(); 
  • 同时使用stdout和stderr。您需要同时执行此操作以避免阻塞行为。有关更多详细信息,请参阅
  • 通过
    process.waitFor()

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

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

    更多细节有待商榷。

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

    我以前已经考虑过这种可能性,但这并不可靠。
    ProcessBuilder pb = new ProcessBuilder("find -type l");
    pb.directory(dir).redirectErrorStream(true);
    Process p = pb.start();