Vejledning til java.lang.Process API

1. Introduktion

I denne vejledning skal vi tage et dybtgående kig på Behandle API.

For et grundere kig på, hvordan man bruger Behandle for at udføre en shell-kommando kan vi henvise til vores tidligere tutorial her.

Processen, som den henviser til, er en udførelsesapplikation. Det Behandle klasse giver metoder til interaktion med disse processer, herunder udpakning af output, udførelse af input, overvågning af livscyklussen, kontrol af udgangsstatus og destruktion (dræbning) af det.

2. Brug Behandle Klasse til kompilering og kørsel af Java-program

Lad os se et eksempel på at kompilere og køre et andet Java-program ved hjælp af Behandle API:

@Test offentlig ugyldig nårExecutedFromAnotherProgram_thenSourceProgramOutput3 () kaster IOException {Process process = Runtime.getRuntime () .exec ("javac -cp src src \ main \ java \ com \ baeldung \ java9 \ process \ OutavaStreamEx "); proces = Runtime.getRuntime () .exec ("java -cp src / main / java com.baeldung.java9.process.OutputStreamExample"); BufferedReader output = ny BufferedReader (ny InputStreamReader (process.getInputStream ())); int-værdi = Integer.parseInt (output.readLine ()); assertEquals (3, værdi); }

Således er applikationerne til at udføre Java-kode inden for en eksisterende Java-kode næsten ubegrænsede.

3. Oprettelse af proces

Vores Java-applikation kan påkalde ethvert program, der kører inden for vores computersystem, der er underlagt begrænsninger for operativsystemet.

Derfor kan vi udføre applikationer. Lad os se, hvilke forskellige brugssager vi kan køre ved at bruge Process API.

Det ProcessBuilder klasse giver os mulighed for at oprette underprocesser i vores applikation.

Lad os se en demo af åbning af Windows-baseret Notepad-applikation:

ProcessBuilder builder = ny ProcessBuilder ("notepad.exe"); Process proces = builder.start ();

4. Ødelæggelsesproces

Behandle giver os også metoder til at ødelægge delprocesser eller processer. Selvom det afhænger af platformen, hvordan applikationen dræbes.

Lad os se forskellige brugstilfælde, som er mulige.

4.1. Ødelægge en proces ved henvisning

Lad os sige, at vi bruger Windows OS og ønsker at gyde Notepad-applikationen og ødelægge den.

Som før kan vi oprette en forekomst af Notepad-applikationen ved hjælp af ProcessBuilder klasse og Start() metode.

Så kan vi kalde ødelægge() metode på vores Behandle objekt.

4.2. Ødelægge en proces med ID

Vi kan også dræbe processer, der kører i vores operativsystem, og som muligvis ikke oprettes af vores applikation.

Forsigtighed skal tilrådes, når du gør dette, da vi ubevidst kan ødelægge en kritisk proces, der kan gøre operativsystemet ustabilt.

Vi skal først finde ud af proces-id'et for den aktuelle kørende proces ved at kontrollere task manager og finde ud af pid.

Lad os se et eksempel:

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

4.3. At ødelægge en proces med magt

Ved udførelsen af ødelægge() metode, vil underprocessen blive dræbt som vi så tidligere i artiklen.

I tilfælde af hvornår ødelægge() fungerer ikke, vi har muligheden for ødelæggeForcibly ().

Vi skal altid starte med ødelægge() metode først. Derefter kan vi udføre en hurtig kontrol af delprocessen, enten ved at udføre er i live().

Hvis det returnerer sandt, skal du udføre ødelæggeForcibly ():

ProcessBuilder builder = ny ProcessBuilder ("notepad.exe"); Process proces = builder.start (); process.destroy (); hvis (process.isAlive ()) {process.destroyForcibly (); }

5. Venter på, at en proces er afsluttet

Vi har også to overbelastede metoder, hvorigennem vi kan sikre, at vi kan vente på, at en proces er afsluttet.

5.1. vent på()

Når denne metode udføres, placeres den den aktuelle udførelsesprocestråd i en blokerende-ventetilstand, medmindre underprocessen bliver afsluttet.

Lad os se på eksemplet:

ProcessBuilder builder = ny ProcessBuilder ("notepad.exe"); Process proces = builder.start (); assertThat (process.waitFor ()> = 0); 

Vi kan se fra ovenstående eksempel for, at den aktuelle tråd fortsætter udførelsen, vil den fortsætte med at vente på, at underprocessetråden slutter. Når underprocessen er afsluttet, fortsætter den aktuelle tråd sin eksekvering.

5.2. waitfor (lang tidOut, TimeUnit tid)

Når denne metode udføres, placeres den den aktuelle udførelsesprocestråd i blokerings-ventetilstand, medmindre underprocessen bliver afsluttet eller løber tør for tid.

Lad os se på eksemplet:

ProcessBuilder builder = ny ProcessBuilder ("notepad.exe"); Process proces = builder.start (); assertFalse (process.waitFor (1, TimeUnit.SECONDS));

Vi kan fra ovenstående eksempel se, at den aktuelle tråd fortsætter med at udføre, at den fortsætter med at vente på, at underprocessetråden slutter, eller hvis det angivne tidsinterval er forløbet.

Når denne metode udføres, returnerer den en boolsk værdi af sand, hvis delprocessen er afsluttet eller en boolsk værdi falsk, hvis ventetiden var gået, før delprocessen var afsluttet.

6. exitValue ()

Når denne metode køres, venter den aktuelle tråd ikke på, at delprocessen bliver afsluttet eller ødelagt, men den vil kaste en IllegalThreadStateException hvis delprocessen ikke afsluttes.

En anden vej rundt, hvis delprocessen er afsluttet med succes, vil det resultere i en exitværdi af processen.

Det kan være ethvert muligt positivt heltal.

Lad os se på et eksempel, når exitValue () metoden returnerer et positivt heltal, når underprocessen er afsluttet med succes:

@Test offentlig ugyldighed givenSubProcess_whenCurrentThreadWillNotWaitIndefinitelyforSubProcessToEnd_thenProcessExitValueReturnsGrt0 () kaster IOException {ProcessBuilder builder = ny ProcessBuilder ("notepad.exe"); Process proces = builder.start (); assertThat (process.exitValue ()> = 0); }

7. er i live()

Når vi gerne vil udføre forretningsbehandling, som er subjektiv, om processen er i live eller ej.

Vi kan udføre en hurtig kontrol for at finde ud af, om processen er i live eller ej, som returnerer en boolsk værdi.

Lad os se et hurtigt eksempel på det:

ProcessBuilder builder = ny ProcessBuilder ("notepad.exe"); Process proces = builder.start (); Tråd. Søvn (10000); process.destroy (); assertTrue (process.isAlive ());

8. Håndtering af processtrømme

Som standard har den oprettede underproces ikke sin terminal eller konsol. Alle dens standard I / O (dvs. stdin, stdout, stderr) operationer vil blive sendt til den overordnede proces. Derved kan den overordnede proces bruge disse strømme til at føde input til og få output fra underprocessen.

Derfor giver dette os en enorm mængde fleksibilitet, da det giver os kontrol over input / output af vores delproces.

8.1. getErrorStream ()

Interessant kan vi hente de fejl, der genereres fra underprocessen, og derefter udføre forretningsbehandling.

Derefter kan vi udføre specifikke forretningsbehandlingschecks baseret på vores krav.

Lad os se et eksempel:

@Test offentlig ugyldighed givenSubProcess_whenEncounterError_thenErrorStreamNotNull () kaster IOException {Process process = Runtime.getRuntime (). Exec ("javac -cp src src \ main \ java \ com \ baeldung \ java9 \ proces \ proces "); BufferedReader-fejl = ny BufferedReader (ny InputStreamReader (process.getErrorStream ())); String errorString = error.readLine (); assertNotNull (errorString); }

8.2. getInputStream ()

Vi kan også hente det output, der genereres af en underproces og forbruge inden for den overordnede proces, hvorved vi kan dele information mellem processerne:

@Test offentlig ugyldighed givenSourceProgram_whenReadingInputStream_thenFirstLineEquals3 () kaster IOException {Process process = Runtime.getRuntime (). Exec ("javac -cp src src \ main \ java \ com \ baeldung \ java9 \ proces \ process \ "); proces = Runtime.getRuntime () .exec ("java -cp src / main / java com.baeldung.java9.process.OutputStreamExample"); BufferedReader output = ny BufferedReader (ny InputStreamReader (process.getInputStream ())); int-værdi = Integer.parseInt (output.readLine ()); assertEquals (3, værdi); }

8.3. getOutputStream ()

Vi kan sende input til en underproces fra en overordnet proces:

Writer w = new OutputStreamWriter (process.getOutputStream (), "UTF-8"); w.write ("send til barn \ n");

8.4. Filtrer processtrømme

Det er en perfekt gyldig brugssag til at interagere med selektive kørende processer.

Behandle giver os mulighed for selektivt at filtrere kørende processer baseret på et bestemt predikat.

Derefter kan vi udføre forretningsoperationer på dette selektive processæt:

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

9. Konklusion

Behandle er en stærk klasse til interaktion mellem operativsystemniveau. Udløsning af terminalkommandoer samt lancering, overvågning og drab af applikationer.

For mere læsning om Java 9 Process API, se vores artikel her.

Som altid finder du kilderne på Github.