Panduan untuk java.lang.Process API

1. Pengenalan

Dalam tutorial ini, kita akan melihat API Proses secara mendalam .

Untuk melihat dangkal bagaimana menggunakan Proses untuk melaksanakan perintah shell, kita boleh merujuk tutorial sebelumnya di sini.

Proses yang dirujuknya adalah aplikasi pelaksanaan. The Process kelas menyediakan kaedah untuk berinteraksi dengan proses ini termasuk mengeluarkan output, melaksanakan input, memantau kitaran hayat, memeriksa status jalan keluar, dan memusnahkan (membunuh) itu.

2. Menggunakan Kelas Proses untuk Menyusun dan Menjalankan Program Java

Mari kita lihat contoh untuk menyusun dan menjalankan program Java yang lain dengan bantuan Process API:

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

Oleh itu, aplikasi pelaksanaan kod Java dalam kod Java yang ada hampir tidak terbatas.

3. Proses Membuat

Aplikasi Java kami dapat memanggil setiap aplikasi yang berjalan di dalam sistem komputer kami yang tertakluk kepada sekatan Sistem Operasi.

Oleh itu kita boleh melaksanakan aplikasi. Mari kita lihat apa kes penggunaan yang boleh kita jalankan dengan menggunakan API Proses.

The ProcessBuilder kelas membolehkan kita untuk membuat subprocesses dalam aplikasi kami.

Mari lihat demo membuka aplikasi Notepad berasaskan Windows:

ProcessBuilder builder = new ProcessBuilder("notepad.exe"); Process process = builder.start();

4. Memusnahkan Proses

Proses juga memberi kita kaedah untuk menghancurkan sub-proses atau proses. Walaupun, bagaimana aplikasi dibunuh bergantung pada platform .

Mari kita lihat pelbagai kes penggunaan yang mungkin.

4.1. Menghancurkan Proses dengan Rujukan

Katakan kita menggunakan OS Windows dan ingin memunculkan aplikasi Notepad dan menghancurkannya.

Seperti sebelumnya, kita dapat membuat contoh aplikasi Notepad dengan menggunakan kelas ProcessBuilder dan kaedah start () .

Kemudian kita boleh memanggil kaedah destruktif () pada objek Proses kita .

4.2. Menghancurkan Proses dengan ID

Kami juga boleh membunuh proses yang berjalan di dalam Sistem Operasi kami yang mungkin tidak dibuat oleh aplikasi kami.

Perlu berhati-hati semasa melakukan ini, kerana kita secara tidak sengaja dapat menghancurkan proses kritikal yang mungkin membuat sistem operasi tidak stabil .

Mula-mula kita perlu mengetahui ID proses proses yang sedang berjalan dengan memeriksa pengurus tugas dan mengetahui pid.

Mari lihat contoh:

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

4.3. Menghancurkan Proses secara Paksa

Pada pelaksanaan kaedah menghancurkan () , subproses akan terbunuh seperti yang kita lihat sebelumnya dalam artikel.

Dalam kes apabila memusnahkan () tidak kerja, kita mempunyai pilihan untuk destroyForcibly () .

Kita harus selalu memulakan dengan kaedah destruktif () terlebih dahulu. Selepas itu, kita dapat melakukan pemeriksaan cepat pada sub-proses sama ada dengan menjalankan isAlive () .

Jika ia kembali benar kemudian melaksanakan destroyForcibly () :

ProcessBuilder builder = new ProcessBuilder("notepad.exe"); Process process = builder.start(); process.destroy(); if (process.isAlive()) { process.destroyForcibly(); }

5. Menunggu Proses Selesai

Kami juga mempunyai dua kaedah yang terlalu banyak, di mana kami dapat memastikan kami dapat menunggu proses selesai.

5.1. menunggu ()

Apabila kaedah ini dijalankan, maka ia akan meletakkan utas proses pelaksanaan semasa dalam keadaan tunggu-tunggu kecuali sub-proses ditamatkan .

Mari lihat contohnya:

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

Kita dapat melihat dari contoh di atas agar thread semasa meneruskan pelaksanaannya akan terus menunggu untaian subproses berakhir. Setelah subproses berakhir, utas semasa akan meneruskan pelaksanaannya.

5.2. penantian (lama waktu Keluar, masa TimeUnit)

Apabila kaedah ini dijalankan, maka ia akan meletakkan utas proses pelaksanaan semasa dalam keadaan tunggu-tunggu kecuali sub-proses ditamatkan atau kehabisan waktu .

Mari lihat contohnya:

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

Kita dapat melihat dari contoh di atas agar thread semasa terus dijalankan, ia akan terus menunggu benang subproses berakhir atau jika selang waktu yang ditentukan telah berlalu.

Apabila kaedah ini dijalankan, maka akan mengembalikan nilai boolean true jika subproses telah keluar atau nilai boolean salah jika waktu menunggu telah berlalu sebelum subproses keluar.

6. keluar Nilai ()

When this method is run then the current thread won't wait for the sub-process to get terminated or destroyed, however, it will throw an IllegalThreadStateException if the subprocess isn't terminated.

Another way around if the subprocess has been successfully terminated then it will result in an exit value of the process.

It can be any possible positive integer number.

Let's look at an example when the exitValue() method returns a positive integer when the subprocess has been terminated successfully:

@Test public void givenSubProcess_whenCurrentThreadWillNotWaitIndefinitelyforSubProcessToEnd_thenProcessExitValueReturnsGrt0() throws IOException { ProcessBuilder builder = new ProcessBuilder("notepad.exe"); Process process = builder.start(); assertThat(process.exitValue() >= 0); }

7. isAlive()

When we'd like to perform business processing which is subjective whether the process is alive or not.

We can perform a quick check to find whether the process is alive or not which returns a boolean value.

Let's see a quick example of it:

ProcessBuilder builder = new ProcessBuilder("notepad.exe"); Process process = builder.start(); Thread.sleep(10000); process.destroy(); assertTrue(process.isAlive());

8. Handling Process Streams

By default, the created subprocess does not have its terminal or console. All its standard I/O (i.e., stdin, stdout, stderr) operations will be sent to the parent process. Thereby the parent process can use these streams to feed input to and get output from the subprocess.

Consequently, this gives us a huge amount of flexibility as it gives us control over the input/output of our sub-process.

8.1. getErrorStream()

Interestingly we can fetch the errors generated from the subprocess and thereon perform business processing.

After that, we can execute specific business processing checks based on our requirements.

Let's see an example:

@Test public void givenSubProcess_whenEncounterError_thenErrorStreamNotNull() throws IOException { Process process = Runtime.getRuntime().exec( "javac -cp src src\\main\\java\\com\\baeldung\\java9\\process\\ProcessCompilationError.java"); BufferedReader error = new BufferedReader(new InputStreamReader(process.getErrorStream())); String errorString = error.readLine(); assertNotNull(errorString); }

8.2. getInputStream()

We can also fetch the output generated by a subprocess and consume within the parent process thus allowing share information between the processes:

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

8.3. getOutputStream()

We can send input to a subprocess from a parent process:

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

8.4. Filter Process Streams

It's a perfectly valid use-case to interact with selective running processes.

Process provides us the facility to selectively filter running processes based on a certain predicate.

After that we can perform business operations on this selective process set:

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

9. Conclusion

Process is a powerful class for Operating System level interaction. Triggering terminal commands as well as launching, monitoring and killing applications.

For more reading on the Java 9 Process API, take a look at our article here.

Seperti biasa, anda akan menemui sumbernya di Github.