Внешняя программа из нашей Java-программы - PullRequest
2 голосов
/ 21 января 2009

Как я могу написать программу на Java, которая будет выполнять другую программу? Кроме того, ввод этой программы должен быть получен из нашей программы, а вывод этой программы должен быть записан в файл.

Это мой небольшой набор кода, чтобы получить его вывод:

Process p = Runtime.getRuntime().exec("C:\\j2sdk1.4.0\bin\\helloworld.java");
BufferedReader input =
        new BufferedReader(new InputStreamReader(p.getInputStream()));
while ((line = input.readLine()) != null) 
  System.out.println(line);

input.close();

Это был мой набор кода, но это выдает IOException.

Ответы [ 5 ]

5 голосов
/ 21 января 2009

API, который Java предлагает для этого, - ProcessBuilder . Установить рабочий каталог и передать параметры относительно просто.

Немного сложно передать STDIN и прочитать STDERR и STDOUT, по крайней мере, для их нетривиальных размеров, потому что вам нужно запустить отдельные потоки, чтобы убедиться, что соответствующие буферы очищены. В противном случае приложение, которое вы вызвали, может блокироваться до тех пор, пока оно не сможет записать больше выходных данных, и если вы также дождитесь завершения этого процесса (не убедившись, что STDOUT будет прочитано), вы заблокируетесь.

4 голосов
/ 21 января 2009

Если вы хотите запускать только другие программы, вы можете использовать метод exec следующим образом:

Runtime r = Runtime.getRuntime();
mStartProcess = r.exec(applicationName, null, fileToExecute);

StreamLogger outputGobbler = new StreamLogger(mStartProcess.getInputStream());
outputGobbler.start();

int returnCode = mStartProcess.waitFor();


class StreamLogger extends Thread{

   private InputStream mInputStream;

   public StreamLogger(InputStream is) {
        this.mInputStream = is;
    }

   public void run() {
        try {
            InputStreamReader isr = new InputStreamReader(mInputStream);
            BufferedReader br = new BufferedReader(isr);
            String line = null;
            while ((line = br.readLine()) != null) {
                    System.out.println(line);
            }
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
    }

}

Exec:

public Process exec(String command, String envp[], File dir) 



   @param      command   a specified system command.
   @param      envp      array of strings, each element of which 
                         has environment variable settings in format
                         <i>name</i>=<i>value</i>.
   @param      dir       the working directory of the subprocess, or
                         <tt>null</tt> if the subprocess should inherit
                         the working directory of the current process.
4 голосов
/ 21 января 2009

Вы можете использовать java.lang.Process и java.lang.ProcessBuilder . Вы взаимодействуете с вводом / выводом процесса, используя getInputStream / getOutputStream / getErrorStream.

Однако есть библиотека Apache Commons под названием Exec , которая разработана, чтобы сделать все это проще. (Обычно это может вызывать затруднения, когда дело доходит до цитирования параметров командной строки и т. Д.) Я сам не использовал Exec, но стоит проверить.

2 голосов
/ 22 января 2009

Пожалуйста, не редактируйте свой вопрос, чтобы он больше не соответствовал исходным ответам. Если у вас есть дополнительный вопрос, четко пометьте их как таковые или задайте их как отдельные вопросы, или используйте комментарии или что-то подобное.

Что касается вашего IOException, пожалуйста, дайте сообщение об ошибке, которое оно показывает.

Кроме того, создается впечатление, что вы пытаетесь запустить файл ".java" напрямую. Это не будет работать. Методы, описанные здесь, предназначены для запуска собственных двоичных исполняемых файлов. Если вы хотите запустить файл ".java", вы должны скомпилировать его в класс и вызвать метод класса main .

1 голос
/ 21 января 2009

На какой ты платформе?

Если вы используете * nix, вы можете ввести:

Java MyProgram | myexternalprogram> myfilename.txt

...