Veiledning til java.lang.Process API

1. Introduksjon

I denne opplæringen skal vi ta en grundig titt på Prosess API.

For en grunnere titt på hvordan du bruker Prosess for å utføre en skallkommando, kan vi referere til vår forrige opplæring her.

Prosessen den refererer til er en kjørende applikasjon. De Prosess class gir metoder for å samhandle med disse prosessene, inkludert å trekke ut utdata, utføre input, overvåke livssyklusen, kontrollere utgangsstatusen og ødelegge (drepe) den.

2. Bruke Prosess Klasse for kompilering og kjøring av Java-program

La oss se et eksempel for å kompilere og kjøre et annet Java-program ved hjelp av Prosess 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 "); prosess = Runtime.getRuntime () .exec ("java -cp src / main / java com.baeldung.java9.process.OutputStreamExample"); BufferedReader output = new BufferedReader (new InputStreamReader (process.getInputStream ())); int-verdi = Integer.parseInt (output.readLine ()); assertEquals (3, verdi); }

Dermed er applikasjonene for å utføre Java-kode i en eksisterende Java-kode praktisk talt ubegrensede.

3. Opprette prosess

Java-applikasjonen vår kan påkalle alle applikasjoner som kjører innenfor vårt datasystem som er underlagt begrensninger for operativsystemet.

Derfor kan vi utføre søknader. La oss se hva de forskjellige brukssakene vi kan kjøre ved å bruke Process API.

De ProcessBuilder klasse tillater oss å lage underprosesser i applikasjonen vår.

La oss se en demo av å åpne Windows-basert Notisblokk-applikasjon:

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

4. Ødeleggelsesprosess

Prosess gir oss også metoder for å ødelegge delprosesser eller prosesser. Selv om hvordan applikasjonen blir drept er plattformavhengig.

La oss se forskjellige brukstilfeller som er mulige.

4.1. Å ødelegge en prosess ved referanse

La oss si at vi bruker Windows OS og ønsker å gyte Notepad-applikasjonen og ødelegge den.

Som før kan vi opprette en forekomst av Notisblokk-applikasjonen ved å bruke ProcessBuilder klasse og start() metode.

Så kan vi ringe ødelegge() metode på vår Prosess gjenstand.

4.2. Å ødelegge en prosess etter ID

Vi kan også drepe prosesser som kjører i operativsystemet vårt, og som ikke kan opprettes av applikasjonen vår.

Forsiktighet bør tilrådes når du gjør dette, da vi uvitende kan ødelegge en kritisk prosess som kan gjøre operativsystemet ustabilt.

Vi må først finne ut prosess-ID-en for den nåværende kjøringsprosessen ved å sjekke oppgavebehandling og finne ut pid.

La oss se et eksempel:

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

4.3. Å ødelegge en prosess med makt

På gjennomføringen av ødelegge() metode, vil underprosessen bli drept som vi så tidligere i artikkelen.

I tilfelle når ødelegge() fungerer ikke, vi har muligheten til ødelegge tvinges ().

Vi bør alltid begynne med ødelegge() metoden først. Etter det kan vi utføre en rask sjekk på underprosessen enten ved å utføre er i live().

Hvis det blir sant, så utfør ødelegge tvinges ():

ProcessBuilder builder = ny ProcessBuilder ("notepad.exe"); Prosessprosess = builder.start (); prosess. ødelegge (); hvis (process.isAlive ()) {process.destroyForcibly (); }

5. Venter på at en prosess skal fullføres

Vi har også to overbelastede metoder, som vi kan sikre at vi kan vente på å fullføre en prosess.

5.1. vent for()

Når denne metoden utføres, vil den plasseres gjeldende kjøringsprosesstråd i blokkerings-vente-tilstand med mindre delprosessen blir avsluttet.

La oss ta en titt på eksemplet:

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

Vi kan se fra eksemplet ovenfor at gjeldende tråd for å fortsette kjøringen, vil fortsette å vente på at underprosess tråden skal slutte. Når delprosessen er avsluttet, vil den gjeldende tråden fortsette kjøringen.

5.2. waitfor (lang tidOut, TimeUnit tid)

Når denne metoden utføres, vil den plasseres den nåværende kjøringsprosesstråden i blokkerings-vente-tilstand med mindre delprosessen blir avsluttet eller går ut på tide.

La oss ta en titt på eksemplet:

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

Vi kan se fra eksemplet ovenfor at gjeldende tråd for å fortsette kjøringen, vil fortsette å vente på at underprosess tråden skal slutte, eller hvis det angitte tidsintervallet har gått.

Når denne metoden kjøres, vil den returnere en boolsk verdi på sann hvis delprosessen har avsluttet eller en boolsk verdi falsk hvis ventetiden hadde gått før underprosessen gikk ut.

6. exitValue ()

Når denne metoden kjøres, vil den gjeldende tråden ikke vente på at underprosessen blir avsluttet eller ødelagt, men den vil kaste en IllegalThreadStateException hvis delprosessen ikke avsluttes.

En annen vei hvis delprosessen er avsluttet, vil det resultere i en avslutningsverdi av prosessen.

Det kan være hvilket som helst positivt heltall.

La oss se på et eksempel når exitValue () metoden returnerer et positivt heltall når underprosessen er avsluttet med hell:

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

7. er i live()

Når vi ønsker å utføre forretningsbehandling som er subjektiv om prosessen er i live eller ikke.

Vi kan utføre en rask sjekk for å finne ut om prosessen er i live eller ikke, som gir en boolsk verdi.

La oss se et raskt eksempel på det:

ProcessBuilder builder = ny ProcessBuilder ("notepad.exe"); Prosessprosess = builder.start (); Tråd. Søvn (10000); prosess. ødelegge (); assertTrue (process.isAlive ());

8. Håndtering av prosessstrømmer

Som standard har ikke den opprettede underprosessen sin terminal eller konsoll. Alle standard I / O-operasjoner (dvs. stdin, stdout, stderr) vil bli sendt til den overordnede prosessen. Dermed kan foreldreprosessen bruke disse strømningene til å mate inngang til og få utgang fra underprosessen.

Følgelig gir dette oss en enorm mengde fleksibilitet ettersom det gir oss kontroll over input / output av delprosessen.

8.1. getErrorStream ()

Det er interessant at vi kan hente feilene generert fra underprosessen og deretter utføre forretningsbehandling.

Etter det kan vi utføre spesifikke forretningskontroller basert på våre krav.

La oss se et eksempel:

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

8.2. getInputStream ()

Vi kan også hente utdata generert av en underprosess og konsumere i foreldreprosessen, slik at vi kan dele informasjon mellom prosessene:

@Test offentlig ugyldig givenSourceProgram_whenReadingInputStream_thenFirstLineEquals3 () kaster IOException {Process process = Runtime.getRuntime (). Exec ("javac -cp src src \ main \ java \ com \ baeldung \ java9 \Stream \ "); prosess = Runtime.getRuntime () .exec ("java -cp src / main / java com.baeldung.java9.process.OutputStreamExample"); BufferedReader output = new BufferedReader (new InputStreamReader (process.getInputStream ())); int-verdi = Integer.parseInt (output.readLine ()); assertEquals (3, verdi); }

8.3. getOutputStream ()

Vi kan sende innspill til en underprosess fra en overordnet prosess:

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

8.4. Filtrer prosessstrømmer

Det er en perfekt gyldig brukstilfelle for å samhandle med selektive kjørende prosesser.

Prosess gir oss muligheten til å selektivt filtrere kjørende prosesser basert på et bestemt predikat.

Etter det kan vi utføre forretningsdrift på dette selektive prosess settet:

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

9. Konklusjon

Prosess er en kraftig klasse for operativsystemnivåinteraksjon. Utløse terminalkommandoer, samt å starte, overvåke og drepe applikasjoner.

For mer lesing om Java 9 Process API, ta en titt på artikkelen vår her.

Som alltid finner du kildene på Github.


$config[zx-auto] not found$config[zx-overlay] not found