DOPLNĚK: Tento článek byl nahrazen mým novějším článkem „Java exec with ProcessBuilder and Process“. Zatímco kód v Javě uvedený v tomto návodu funguje v jednoduchých případech „Java exec“, nový článek ukazuje, jak správně číst výstupní proudy ze systémového příkazu ve vláknech Javy a také jak v případě potřeby zapisovat na standardní vstup příkazu.

Neváhejte si přečíst tento článek pro základní/základní informace, ale důrazně doporučuji použít zdrojový kód, který sdílím ve svém novějším článku „Java exec“, protože řeší problémy se standardním vstupem, výstupem a chybami, které jsem v níže uvedeném kódu neřešil správně.

Úvod

O Javě jsem toho přečetl hodně, ale jednou z věcí, o které se málokdy mluví, je, jak byste měli postupovat při spouštění externích systémových příkazů. Samozřejmě se o tom asi moc nedočtete, protože to ubírá na přenositelnosti aplikací v Javě. Pokud například píšete aplikaci v Javě na unixovém systému, mohlo by vás zajímat spouštění příkazu „ps -ef“ a čtení výstupu tohoto příkazu. Pro unixové systémy je to skvělé, ale bohužel stejný program nebude fungovat v systému Windows, protože příkaz ps není ve Windows k dispozici.

No, pro tento článek zapomeneme na přenositelnost a ukážeme si metodu, kterou lze použít ke spouštění systémových příkazů. Na toto téma jsme obdrželi mnoho dotazů, takže jdeme na to.

Diskuse (Runtime exec a Process)

Spustit systémový příkaz je poměrně jednoduché – jakmile to vidíte udělat poprvé. Zahrnuje použití dvou tříd jazyka Java, třídy Runtime a třídy Process. V podstatě použijete metodu exec třídy Runtime ke spuštění příkazu jako samostatného procesu. Vyvolání metody exec vrátí objekt Process pro správu podprocesu. Poté použijete metody getInputStream() a getErrorStream() objektu Process pro čtení normálního výstupu příkazu a chybového výstupu příkazu. Co uděláte s výstupem provedeného příkazu, je zcela na vás a na aplikaci, kterou vytváříte.

(Poznámka: Existuje také metoda getOutputStream(), kterou můžete použít pro zápis do procesu, ale touto metodou se v tomto článku nebudeme zabývat. Té a několika dalším pokročilým funkcím se budeme věnovat v některém z příštích článků.“

Příklad Java exec

Kód uvedený v Listingu 1 představuje funkční příklad naší techniky „Java exec“ v souboru s názvem JavaRunCommand.java.

import java.io.*;public class JavaRunCommand { public static void main(String args) { String s = null; try { // run the Unix "ps -ef" command // using the Runtime exec method: Process p = Runtime.getRuntime().exec("ps -ef"); BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream())); BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream())); // read the output from the command System.out.println("Here is the standard output of the command:\n"); while ((s = stdInput.readLine()) != null) { System.out.println(s); } // read any errors from the attempted command System.out.println("Here is the standard error of the command (if any):\n"); while ((s = stdError.readLine()) != null) { System.out.println(s); } System.exit(0); } catch (IOException e) { System.out.println("exception happened - here's what I know: "); e.printStackTrace(); System.exit(-1); } }}

Listing 1 (výše):

Jak funguje náš kód Java exec

První věc, kterou uděláte, je zadání příkazu, který chcete spustit, dodáním tohoto příkazu třídě Runtime. Protože nemůžete vytvořit vlastní instanci třídy Runtime, použijete nejprve metodu getRuntime pro přístup k aktuálnímu běhovému prostředí a poté zavoláte metodu Runtime exec. Ta vrátí objekt Process.

Všechno ostatní, co děláte, zahrnuje metody objektu Process. V tomto případě, protože spouštíme příkaz „ps -ef“ na unixovém systému, potřebujeme pouze přečíst výstup příkazu. Čtení standardní chyby v tomto případě pravděpodobně není nutné, ale myslel jsem si, že když už ne dobrá programátorská praxe, tak alespoň stojí za to ji ukázat.

Převedu vstupní proudy pomocí InputStreamReader a BufferedReader, abych mohl použít metodu readLine() třídy BufferedReader. Protože používám tyto třídy, nebude tato aplikace správně zkompilována se starším kompilátorem JDK 1.0.x (tyto třídy nebyly v 1.0.x k dispozici).

Stáhněte si zdrojový kód příkladu „Java exec“

O tomto tématu bych mohl dlouze hovořit, ale nejlepší, co vám mohu doporučit, je stáhnout si zdrojový kód a chvíli s ním pracovat. Zkoušejte spouštět různé příkazy, abyste zjistili, zda fungují správně, a zkuste spustit příkaz, který vyžaduje vstup (to bude trochu složitější).