Получение вывода команды в Java: использование getRuntime()
Быстрый ответ
Рассмотрим кратко, как можно получить вывод командной строки в Java. Для этого воспользуемся методом Runtime.exec()
, с помощью которого будем читать вывод, используя BufferedReader
, и затем обрабатывать его.
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();
Управление процессами и организация вывода данных
Работая с внешними процессами, иногда можно столкнуться с некоторыми сложностями. Однако, покажем, как их можно избежать.
Управление командами при помощи ProcessBuilder
ProcessBuilder
это инструмент, предназначенный для детального управления внешними процессами:
ProcessBuilder builder = new ProcessBuilder("your-command");
builder.redirectErrorStream(true);
Process process = builder.start();
// Представленный далее код...
Организация чтения вывода
Если Вы планируете осуществить одновременное чтение стандартного вывода и ошибок, рекомендуется использовать несколько потоков выполнения:
new Thread(() -> {
// Код для чтения стандартного вывода
}).start();
new Thread(() -> {
// Код для чтения вывода ошибок
}).start();
Преобразование и проверка вывода данных
Для преобразования потока вывода в строку используйте IOUtils
из библиотеки Apache commons-io:
String output = IOUtils.toString(process.getInputStream(), StandardCharsets.UTF_8);
Ручное управление и обработка исключений
Properties & Personal Documentй. Запустите команду вне среды Java и убедитесь, что приложение имеет все необходимые для ее исполнения права доступа.
Управление потоками и кодировкой символов
Управление потоками требует бдительности и достаточного планирования.
Кодировка символов
Для корректного чтения данных применяйте InputStreamReader
с необходимой кодировкой:
BufferedReader reader = new BufferedReader(
new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8)
);
// Представленный далее код...
Буферизация потока
Для обработки больших потоков информации следует вести контроль за размерами буферов.
Управление ресурсами: автоматическое закрытие потоков
Для автоматического закрытия потоков используйте конструкцию try-with-resources:
try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
// Ваш код
} // Автоматическое закрытие ресурса
Обработка исключений
Для обработки исключений используйте Process.getErrorStream()
:
BufferedReader reader = new BufferedReader(
new InputStreamReader(process.getErrorStream())
);
// Представленный далее код...
Визуализация
Представьте вывод командной строки в Java, понимая его как получение данных от спутниковой антенны, когда Вы одновременно приемлете стандартный вывод и сообщения об ошибках.
Навигация по потенциальным сложностям
Зависание потоков
При обработке больших объемов данных стоит воспользоваться асинхронным чтением или комбинацией PipedInputStream
и PipedOutputStream
.
Обработка "висячих" процессов
Испольуйте метод ожидания с таймаутом для управления процессами, которые задерживают выполнение:
if (!process.waitFor(1, TimeUnit.MINUTES)) {
// Логика по обработке случая превышения времени ожидания
}
Профессиональная обработка исключений и тестирование
Удостоверьтесь, что ваш код корректно работает в различных средах исполнения и с различными командными утилитами.
Полезные материалы
- Runtime (Java Platform SE 8)
- ProcessBuilder (Java Platform SE 8)
- ProcessBuilder: Перенаправление stdout и stderr запущенных процессов без блокировки основного потока – Stack Overflow
- Apache Commons Exec – Apache Commons Exec
- GitHub – apache/commons-exec: Apache Commons Exec
- Выполнение команд оболочки с помощью Java – DZone