Как читать выходные данные командной строки из Java (через Runtime.getRuntime (). Exec (...)) - PullRequest
0 голосов
/ 18 сентября 2010

Я пытаюсь представить некоторую информацию в приложении Swing о существовании символических ссылок.Графический интерфейс имеет 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");
}

Я попытался заменить 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 в последней строке.Кажется, что-то зависает, хотя графический интерфейс остается отзывчивым.

Я получаю следующую трассировку стека при закрытии диалогового окна:

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: Операционная система - 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 ]

1 голос
/ 18 сентября 2010

Вы не говорите, какую ОС вы используете.Предполагая, что ваш find синтаксис команды правильный (он не корректен в Mac OSX), я думаю, что вы должны:

  1. использовать и stdout, и stderr.Вам нужно сделать это одновременно , чтобы избежать блокирующего поведения.См. этот ответ SO для получения более подробной информации
  2. сбор кода выхода из порожденного процесса через Process.waitFor()
0 голосов
/ 23 сентября 2010

Я обнаружил проблему: метод не был вызван из потока диспетчеризации событий после создания графического интерфейса.

0 голосов
/ 19 сентября 2010

Вместо запуска команды Unix для поиска символических ссылок вы можете сделать это на Java, сравнив результаты File.getCanonicalPath() и File.getAbsolutePath().

Подробнее в этом вопросе.

...