UPDATE: Acest articol a fost înlocuit cu articolul meu mai nou „Java exec with ProcessBuilder and Process”. În timp ce codul Java prezentat în acest tutorial funcționează în cazuri simple de „Java exec”, noul articol arată cum să citiți corect fluxurile de ieșire de la comanda de sistem în firele Java și, de asemenea, cum să scrieți la intrarea standard a comenzii, dacă este necesar.
Nu ezitați să citiți acest articol pentru informații de fond/legate, dar vă recomand cu tărie să folosiți codul sursă pe care îl împărtășesc în noul meu articol „Java exec”, deoarece acesta rezolvă problemele de intrare standard, ieșire și eroare pe care nu le-am gestionat corespunzător în codul de mai jos.
Introducere
Am citit multe despre Java, dar unul dintre lucrurile pe care le văd rar discutate este modul în care ar trebui să procedați pentru a rula comenzi de sistem externe. Bineînțeles, probabil că nu citiți prea multe despre acest lucru pentru că diminuează portabilitatea aplicațiilor Java. De exemplu, dacă scrieți o aplicație Java pe un sistem Unix, s-ar putea să fiți interesat să executați comanda „ps -ef” și să citiți rezultatul comenzii. Pentru sistemele Unix, acest lucru este grozav, dar, din păcate, același program nu va funcționa pe un sistem Windows, deoarece comanda ps nu este disponibilă pe Windows.
Ei bine, vom uita de portabilitate pentru acest articol și vom demonstra o metodă care poate fi utilizată pentru a rula comenzi de sistem. Am primit o mulțime de solicitări despre acest subiect, așa că începem.
Discuție (Runtime exec and Process)
Executarea unei comenzi de sistem este relativ simplă – odată ce ați văzut cum se face prima dată. Ea implică utilizarea a două clase Java, clasa Runtime și clasa Process. Practic, utilizați metoda exec a clasei Runtime pentru a rula comanda ca un proces separat. Invocarea metodei exec returnează un obiect Process pentru gestionarea subprocesului. Apoi se utilizează metodele getInputStream()
și getErrorStream()
ale obiectului Process
pentru a citi ieșirea normală a comenzii și ieșirea de eroare a comenzii. Ceea ce faceți cu ieșirea comenzii executate depinde în întregime de dumneavoastră și de aplicația pe care o creați.
(Notă: Există, de asemenea, o metodă getOutputStream()
pe care o puteți utiliza pentru a scrie în proces, dar nu vom aborda această metodă în acest articol. Vom acoperi aceasta și alte câteva caracteristici avansate într-un articol viitor.)
Un exemplu de execuție Java
Codul prezentat în Lista 1 oferă un exemplu funcțional al tehnicii noastre de „execuție Java” într-un fișier numit 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); } }}
Lista 1 (de mai sus): Fișierul JavaRunCommand.java arată cum puteți executa o comandă externă de sistem din interiorul unui program Java.
Cum funcționează codul nostru Java exec
Primul lucru pe care îl faceți este să specificați comanda pe care doriți să o executați furnizând această comandă clasei Runtime. Deoarece nu vă puteți crea propria instanță a clasei Runtime, utilizați mai întâi metoda getRuntime
pentru a accesa mediul de execuție curent și apoi invocați metoda exec Runtime. Aceasta returnează un obiect Process.
Toate celelalte lucruri pe care le faceți implică metode ale obiectului Process. În acest caz, deoarece executăm comanda „ps -ef” pe un sistem Unix, trebuie doar să citim ieșirea comenzii. Citirea erorii standard probabil că nu este necesară în acest caz, dar m-am gândit că cel puțin merită arătat, dacă nu cumva este o bună practică de programare.
Convert fluxurile de intrare cu InputStreamReader și BufferedReader astfel încât să pot folosi metoda readLine()
a clasei BufferedReader. Deoarece folosesc aceste clase, această aplicație nu va compila corect cu un compilator JDK 1.0.x mai vechi (aceste clase nu erau disponibile în 1.0.x).
Descărcați codul sursă al exemplului „Java exec”
Am putea continua îndelung despre acest subiect, dar cel mai bun lucru pe care vi-l pot recomanda este să descărcați codul sursă și să lucrați cu el o vreme. Încercați să executați diferite comenzi pentru a vedea dacă reușiți să le faceți să funcționeze corect și încercați să executați o comandă care necesită introducere de date (acest lucru va fi un pic mai complicat).
.
Lasă un răspuns