Vodič za java.lang.Process API

1. Uvod

U ovom ćemo uputstvu uzeti dubinski pogled na Postupak API.

Za plići uvid u to kako koristiti Postupak za izvršavanje naredbe ljuske možemo se pozvati na naš prethodni tutorial ovdje.

Proces na koji se odnosi je izvršna aplikacija. The Postupak klasa pruža metode za interakciju s tim procesima, uključujući izdvajanje rezultata, izvođenje unosa, nadzor životnog ciklusa, provjeru statusa izlaza i uništavanje (ubijanje).

2. Korištenje Postupak Predavanje za sastavljanje i pokretanje Java programa

Pogledajmo primjer za kompajliranje i pokretanje drugog Java programa uz pomoć Postupak API:

@Test public void whenExecutedFromAnotherProgram_thenSourceProgramOutput3 () baca IOException {Process process = Runtime.getRuntime () .exec ("javac -cp src src \ main \ java \ com \ baeldung \ java9 \ proces \ output \ output \ output \ output \ output \ output \ output \ output \ output \ output \ output \ output \ output \ output \ output \ output \ output \ output \ output \ output \ output \ output \ output \ output \ output \ output \ output \ output \ output \ output \ output \ output \ output \ \ output \ \ \\\\\\\ Iz "); proces = Runtime.getRuntime () .exec ("java -cp src / main / java com.baeldung.java9.process.OutputStreamExample"); Izlaz BufferedReader = novi BufferedReader (novi InputStreamReader (process.getInputStream ())); int vrijednost = Integer.parseInt (output.readLine ()); assertEquals (3, vrijednost); }

Stoga su aplikacije za izvršavanje Java koda unutar postojećeg Java koda gotovo neograničene.

3. Postupak stvaranja

Naša Java aplikacija može pozvati bilo koju aplikaciju koja je pokrenuta u našem računalnom sustavu podložno ograničenjima operativnog sustava.

Stoga možemo izvršavati aplikacije. Pogledajmo koje su različite slučajeve upotrebe koje možemo pokrenuti pomoću API-ja Process.

The ProcessBuilder klasa omogućuje nam stvaranje podprocesa unutar naše aplikacije.

Pogledajmo demonstraciju otvaranja aplikacije Notepad temeljenu na sustavu Windows:

Builder ProcessBuilder = novi ProcessBuilder ("notepad.exe"); Procesni postupak = builder.start ();

4. Proces uništavanja

Postupak također nam pruža metode za uništavanje potprocesa ili procesa. Iako je način na koji se aplikacija ubija ovisi o platformi.

Pogledajmo različite primjere upotrebe koji su mogući.

4.1. Uništavanje postupka referencom

Recimo da koristimo Windows OS i želimo stvoriti aplikaciju Notepad i uništiti je.

Kao i prije, instalaciju aplikacije Notepad možemo stvoriti pomoću ProcessBuilder razred i početak() metoda.

Tada možemo nazvati uništiti() metoda na našem Postupak objekt.

4.2. Uništavanje procesa pomoću ID-a

Također možemo ubiti procese koji se izvode u našem operativnom sustavu, a koje naša aplikacija možda neće stvoriti.

Pri tome treba biti oprezan, jer nesvjesno možemo uništiti kritični proces koji bi operativni sustav mogao učiniti nestabilnim.

Prvo moramo saznati ID procesa trenutnog pokrenutog postupka provjerom upravitelja zadataka i saznati pid.

Pogledajmo primjer:

Neobvezno optionalProcessHandle = ProcessHandle.of (5232); optionalProcessHandle.ifPresent (processHandle -> processHandle.destroy ()); 

4.3. Uništavanje procesa silom

O izvršenju uništiti() metodom, potproces će se ubiti kao što smo vidjeli ranije u članku.

U slučaju kada uništiti() ne radi, imamo mogućnost uništiti na silu ().

Uvijek bismo trebali početi s uništiti() metoda prva. Nakon toga možemo izvršiti brzu provjeru potprocesa da li izvršenjem živ je().

Ako se vrati true, onda izvršite uništiti na silu ():

Builder ProcessBuilder = novi ProcessBuilder ("notepad.exe"); Procesni postupak = builder.start (); process.destroy (); if (process.isAlive ()) {process.destroyForsibly (); }

5. Čekanje da se postupak završi

Također imamo dvije preopterećene metode pomoću kojih možemo osigurati da možemo pričekati završetak postupka.

5.1. čekati()

Kada se ova metoda izvrši, tada će se i primijeniti trenutna nit procesa izvršenja u stanju blokiranja i čekanja, osim ako se potproces ne završi.

Pogledajmo primjer:

Builder ProcessBuilder = novi ProcessBuilder ("notepad.exe"); Procesni postupak = builder.start (); assertThat (process.waitFor ()> = 0); 

Iz gornjeg primjera možemo vidjeti kako će trenutna nit nastaviti s izvršavanjem i dalje će čekati da završi nit potprocesa. Nakon završetka potprocesa, trenutna nit će nastaviti svoje izvršavanje.

5.2. waitfor (long timeOut, TimeUnit vrijeme)

Kada se ova metoda izvrši, tada će se i primijeniti trenutna nit procesa izvršenja u stanju blokiranja-čekanja, osim ako potproces ne završi ili ne istekne vrijeme.

Pogledajmo primjer:

Builder ProcessBuilder = novi ProcessBuilder ("notepad.exe"); Procesni postupak = builder.start (); assertFalse (process.waitFor (1, TimeUnit.SECONDS));

Iz gornjeg primjera možemo vidjeti da će trenutna nit nastaviti s izvršavanjem i dalje će čekati da završi nit potprocesa ili ako je protekao navedeni vremenski interval.

Kada se izvrši ova metoda, vratit će logičku vrijednost true ako je potproces izašao ili logičku vrijednost false ako je vrijeme čekanja proteklo prije nego što je potproces izašao.

6. exitValue ()

Kada se ova metoda pokrene, trenutna nit neće čekati da se potproces završi ili uništi, no bacit će IllegalThreadStateException ako potproces nije prekinut.

Ako je potproces uspješno završen, to će rezultirati izlaznom vrijednošću procesa.

To može biti bilo koji mogući pozitivni cjelobrojni broj.

Pogledajmo primjer kada exitValue () metoda vraća pozitivan cijeli broj kada je potproces uspješno završen:

@Test javna praznina givenSubProcess_whenCurrentThreadWillNotWaitIndefinitelyforSubProcessToEnd_thenProcessExitValueReturnsGrt0 () baca IOException {ProcessBuilder builder = new ProcessBuilder ("notepad.exe"); Procesni postupak = builder.start (); assertThat (process.exitValue ()> = 0); }

7. živ je()

Kada bismo željeli obaviti poslovnu obradu koja je subjektivna bez obzira je li postupak živ ili ne.

Možemo izvršiti brzu provjeru da utvrdimo je li postupak živ ili ne, što vraća logičku vrijednost.

Pogledajmo brzi primjer toga:

Builder ProcessBuilder = novi ProcessBuilder ("notepad.exe"); Procesni postupak = builder.start (); Navoj.spavanje (10000); process.destroy (); assertTrue (process.isAlive ());

8. Rukovanje procesnim tokovima

Prema zadanim postavkama, stvoreni potproces nema svoj terminal ili konzolu. Sve njegove standardne I / O (tj. Stdin, stdout, stderr) operacije bit će poslane nadređenom procesu. Na taj način nadređeni proces može koristiti ove tokove za napajanje ulaza i dobivanje rezultata iz potprocesa.

Slijedom toga, ovo nam daje veliku količinu fleksibilnosti jer nam daje kontrolu nad ulazom / izlazom našeg potprocesa.

8.1. getErrorStream ()

Zanimljivo je da možemo dohvatiti pogreške generirane iz potprocesa i na tome izvršiti poslovnu obradu.

Nakon toga možemo izvršiti određene provjere poslovne obrade na temelju naših zahtjeva.

Pogledajmo primjer:

Public void @Test givenSubProcess_whenEncounterError_thenErrorStreamNotNull () baca IOException {procesa postupka = Runtime.getRuntime (). Exec ( „javac -CP src src \ glavni \ java \ com \ baeldung \ java9 \ postupak \ ProcessCompilationError.java "); Pogreška BufferedReader = novi BufferedReader (novi InputStreamReader (process.getErrorStream ())); Niz errorString = error.readLine (); assertNotNull (errorString); }

8.2. getInputStream ()

Također možemo dohvatiti izlaz koji generira potproces i potrošiti u nadređenom procesu, omogućavajući tako dijeljenje informacija između procesa:

@Test public void givenSourceProgram_whenReadingInputStream_thenFirstLineEquals3 () baca IOException {Process process = Runtime.getRuntime (). Exec ("javac -cp src src \ main \ java \ com \ baeldung \ java9put \ java9put \ java9put. "); proces = Runtime.getRuntime () .exec ("java -cp src / main / java com.baeldung.java9.process.OutputStreamExample"); Izlaz BufferedReader = novi BufferedReader (novi InputStreamReader (process.getInputStream ())); int vrijednost = Integer.parseInt (output.readLine ()); assertEquals (3, vrijednost); }

8.3. getOutputStream ()

Ulaz u podproces možemo poslati iz nadređenog procesa:

Writer w = novi OutputStreamWriter (process.getOutputStream (), "UTF-8"); w.write ("pošalji djetetu \ n");

8.4. Filtrirajte procesne tokove

To je savršeno valjan slučaj upotrebe za interakciju s selektivnim pokrenutim procesima.

Postupak pruža nam mogućnost selektivnog filtriranja pokrenutih procesa na temelju određenog predikata.

Nakon toga možemo obavljati poslovne operacije na ovom selektivnom skupu procesa:

@Test javna praznina givenRunningProcesses_whenFilterOnProcessIdRange_thenGetSelectedProcessPid () {assertThat (((int) ProcessHandle.allProcesses () .filter (ph -> (ph.pid ()> 10000 && ph.pid () 0);}

9. Zaključak

Postupak je moćna klasa za interakciju na razini operativnog sustava. Pokretanje naredbi terminala, kao i pokretanje, nadgledanje i ubijanje aplikacija.

Za više čitanja o Java 9 Process API, pogledajte naš članak ovdje.

Kao i uvijek, izvore ćete pronaći na Githubu.