Получение вывода команды в Java: использование getRuntime()

Пройдите тест, узнайте какой профессии подходите и получите бесплатную карьерную консультацию
В конце подарим скидку до 55% на обучение
Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Рассмотрим кратко, как можно получить вывод командной строки в Java. Для этого воспользуемся методом Runtime.exec(), с помощью которого будем читать вывод, используя BufferedReader, и затем обрабатывать его.

Java
Скопировать код
Process process = Runtime.getRuntime().exec("your-command");
BufferedReader reader = new BufferedReader(
  new InputStreamReader(process.getInputStream())
);

StringBuilder output = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
    output.append(line).append(System.lineSeparator());
}
process.waitFor();
reader.close();

String result = output.toString();
Пройдите тест и узнайте подходит ли вам сфера IT
Пройти тест

Управление процессами и организация вывода данных

Работая с внешними процессами, иногда можно столкнуться с некоторыми сложностями. Однако, покажем, как их можно избежать.

Управление командами при помощи ProcessBuilder

ProcessBuilder это инструмент, предназначенный для детального управления внешними процессами:

Java
Скопировать код
ProcessBuilder builder = new ProcessBuilder("your-command");
builder.redirectErrorStream(true);
Process process = builder.start();
// Представленный далее код...

Организация чтения вывода

Если Вы планируете осуществить одновременное чтение стандартного вывода и ошибок, рекомендуется использовать несколько потоков выполнения:

Java
Скопировать код
new Thread(() -> {
    // Код для чтения стандартного вывода
}).start();

new Thread(() -> {
    // Код для чтения вывода ошибок
}).start();

Преобразование и проверка вывода данных

Для преобразования потока вывода в строку используйте IOUtils из библиотеки Apache commons-io:

Java
Скопировать код
String output = IOUtils.toString(process.getInputStream(), StandardCharsets.UTF_8);

Ручное управление и обработка исключений

Properties & Personal Documentй. Запустите команду вне среды Java и убедитесь, что приложение имеет все необходимые для ее исполнения права доступа.

Управление потоками и кодировкой символов

Управление потоками требует бдительности и достаточного планирования.

Кодировка символов

Для корректного чтения данных применяйте InputStreamReader с необходимой кодировкой:

Java
Скопировать код
BufferedReader reader = new BufferedReader(
  new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8)
);
// Представленный далее код...

Буферизация потока

Для обработки больших потоков информации следует вести контроль за размерами буферов.

Управление ресурсами: автоматическое закрытие потоков

Для автоматического закрытия потоков используйте конструкцию try-with-resources:

Java
Скопировать код
try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
    // Ваш код
} // Автоматическое закрытие ресурса

Обработка исключений

Для обработки исключений используйте Process.getErrorStream():

Java
Скопировать код
BufferedReader reader = new BufferedReader(
  new InputStreamReader(process.getErrorStream())
);
// Представленный далее код...

Визуализация

Представьте вывод командной строки в Java, понимая его как получение данных от спутниковой антенны, когда Вы одновременно приемлете стандартный вывод и сообщения об ошибках.

Навигация по потенциальным сложностям

Зависание потоков

При обработке больших объемов данных стоит воспользоваться асинхронным чтением или комбинацией PipedInputStream и PipedOutputStream.

Обработка "висячих" процессов

Испольуйте метод ожидания с таймаутом для управления процессами, которые задерживают выполнение:

Java
Скопировать код
if (!process.waitFor(1, TimeUnit.MINUTES)) {
    // Логика по обработке случая превышения времени ожидания
}

Профессиональная обработка исключений и тестирование

Удостоверьтесь, что ваш код корректно работает в различных средах исполнения и с различными командными утилитами.

Полезные материалы

  1. Runtime (Java Platform SE 8)
  2. ProcessBuilder (Java Platform SE 8)
  3. ProcessBuilder: Перенаправление stdout и stderr запущенных процессов без блокировки основного потока – Stack Overflow
  4. Apache Commons Exec – Apache Commons Exec
  5. GitHub – apache/commons-exec: Apache Commons Exec
  6. Выполнение команд оболочки с помощью Java – DZone