Java中的ProcessBuilder類詳細(xì)解析
一、ProcessBuilder基礎(chǔ)
1、ProcessBuilder類
1.1 概述
ProcessBuilder類是J2SE 1.5在java.lang中新添加的一個(gè)新類,此類用于創(chuàng)建操作系統(tǒng)進(jìn)程,它提供一種啟動(dòng)和管理進(jìn)程(也就是應(yīng)用程序)的方法。在J2SE 1.5之前,都是由Process類處理實(shí)現(xiàn)進(jìn)程的控制管理。
每個(gè)ProcessBuilder 實(shí)例管理一個(gè)進(jìn)程屬性集,它的start()方法利用這些屬性創(chuàng)建一個(gè)新的 Process 實(shí)例。start()方法可以從同一實(shí)例重復(fù)調(diào)用,以利用相同的或相關(guān)的屬性創(chuàng)建新的子進(jìn)程。
1.2 進(jìn)程屬性
命令 command
表示要調(diào)用的外部程序文件及其參數(shù)(如果有)。
環(huán)境 environment
從變量到值依賴于系統(tǒng)的映射。初始值是當(dāng)前進(jìn)程環(huán)境的一個(gè)副本(請參閱System.getenv())。
工作目錄 working directory
默認(rèn)值是當(dāng)前進(jìn)程的當(dāng)前工作目錄,通常根據(jù)系統(tǒng)屬性 user.dir 來命名。
redirectErrorStream屬性
此屬性為 false意思是子進(jìn)程的標(biāo)準(zhǔn)輸出和錯(cuò)誤輸出被發(fā)送給兩個(gè)獨(dú)立的流,這些流可以通過 Process.getInputStream() 和 Process.getErrorStream()方法來訪問。如果將值設(shè)置為 true,標(biāo)準(zhǔn)錯(cuò)誤將與標(biāo)準(zhǔn)輸出合并,在此情況下,合并的數(shù)據(jù)可從 Process.getInputStream() 返回的流讀取,而從 Process.getErrorStream() 返回的流讀取將直接到達(dá)文件尾。
ProcessBuilder pb = new ProcessBuilder("myCommand", "myArg1", "myArg2"); Map<String, String> env = pb.environment(); env.put("VAR1", "myValue"); env.remove("OTHERVAR"); env.put("VAR2", env.get("VAR1") + "suffix"); pb.directory("myDir"); Process p = pb.start();
2、Process類
2.1 概述
Process類是一個(gè)抽象類(所有的方法均是抽象的),封裝了一個(gè)進(jìn)程(即一個(gè)執(zhí)行程序)。
Process 類提供了執(zhí)行從進(jìn)程輸入、執(zhí)行輸出到進(jìn)程、等待進(jìn)程完成、檢查進(jìn)程的退出狀態(tài)以及銷毀(殺掉)進(jìn)程的方法。創(chuàng)建的子進(jìn)程沒有自己的終端或控制臺(tái)。它的所有標(biāo)準(zhǔn) io(即 stdin、stdout 和 stderr)操作都將通過三個(gè)流 (getOutputStream()、getInputStream() 和 getErrorStream()) 重定向到父進(jìn)程。父進(jìn)程使用這些流來提供到子進(jìn)程的輸入和獲得從子進(jìn)程的輸出。
2.2 Process抽象類
- destroy()
殺掉子進(jìn)程。
- exitValue()
返回子進(jìn)程的出口值。
- InputStream getErrorStream()
獲得子進(jìn)程的錯(cuò)誤流。
- InputStream getInputStream()
獲得子進(jìn)程的輸入流。
- OutputStream getOutputStream()
獲得子進(jìn)程的輸出流。
- waitFor()
導(dǎo)致當(dāng)前線程等待,如果必要,一直要等到由該 Process 對象表示的進(jìn)程已經(jīng)終止
同時(shí)Process對象可以獲得進(jìn)程句柄,從而可以獲得進(jìn)程ID、父進(jìn)程、子進(jìn)程等信息
2.3 創(chuàng)建Process對象方式
- 使用命令名和命令的參數(shù)選項(xiàng)構(gòu)造ProcessBuilder對象,它的start方法執(zhí)行命令,啟動(dòng)一個(gè)進(jìn)程,返回一個(gè)Process對象
- Runtime.exec()方法創(chuàng)建一個(gè)本機(jī)進(jìn)程,并返回 Process 子類的一個(gè)實(shí)例
3、ProcessBuilder與Runtime.exec()異同
3.1 相同點(diǎn)
ProcessBuilder.start() 和 Runtime.exec() 方法都被用來創(chuàng)建一個(gè)操作系統(tǒng)進(jìn)程(執(zhí)行命令行操作),并返回 Process 子類的一個(gè)實(shí)例,該實(shí)例可用來控制進(jìn)程狀態(tài)并獲得相關(guān)信息
3.2 不同點(diǎn)
ProcessBuilder.start() 和 Runtime.exec()傳遞的參數(shù)有所不同
Runtime.exec()可接受一個(gè)單獨(dú)的字符串,這個(gè)字符串是通過空格來分隔可執(zhí)行命令程序和參數(shù)的;也可以接受字符串?dāng)?shù)組參數(shù)。而ProcessBuilder的構(gòu)造函數(shù)是一個(gè)字符串列表或者數(shù)組。列表中第一個(gè)參數(shù)是可執(zhí)行命令程序,其他的是命令行執(zhí)行是需要的參數(shù)。
二、ProcessBuilder實(shí)戰(zhàn)
1、API介紹
構(gòu)造方法
- ProcessBuilder(List command)利用指定的操作系統(tǒng)程序和參數(shù)構(gòu)造一個(gè)進(jìn)程生成器。
- ProcessBuilder(String… command)利用指定的操作系統(tǒng)程序和參數(shù)構(gòu)造一個(gè)進(jìn)程生成器。
方法
- command()
返回此進(jìn)程生成器的操作系統(tǒng)程序和參數(shù)。
- command(List command)
設(shè)置此進(jìn)程生成器的操作系統(tǒng)程序和參數(shù)。
- command(String… command)
設(shè)置此進(jìn)程生成器的操作系統(tǒng)程序和參數(shù)。
- directory()
返回此進(jìn)程生成器的工作目錄。
- directory(File directory)
設(shè)置此進(jìn)程生成器的工作目錄。
- environment()
返回此進(jìn)程生成器環(huán)境的字符串映射視圖。 environment方法獲得運(yùn)行進(jìn)程的環(huán)境變量,得到一個(gè)Map,可以修改環(huán)境變量
- redirectErrorStream()
通知進(jìn)程生成器是否合并標(biāo)準(zhǔn)錯(cuò)誤和標(biāo)準(zhǔn)輸出。
- redirectErrorStream(boolean redirectErrorStream)
設(shè)置此進(jìn)程生成器的 redirectErrorStream 屬性。
- start()
使用此進(jìn)程生成器的屬性啟動(dòng)一個(gè)新進(jìn)程。
2、實(shí)戰(zhàn)demo
//Runtime.exec()進(jìn)行創(chuàng)建 public static void main(String[] args) { try { Process process = Runtime.getRuntime().exec("ipconfig /all"); InputStream is = process.getInputStream(); InputStreamReader isr =new InputStreamReader(is, "gbk"); BufferedReader br = new BufferedReader(isr); String line; while ((line = br.readLine()) != null) { System.out.println(line); } int exitCode = process.waitFor(); System.out.println(exitCode); } catch (IOException | InterruptedException e) { e.printStackTrace(); } }
public static void main(String[] args) { ProcessBuilder processBuilder = new ProcessBuilder(); // System.out.println(processBuilder.directory()); // System.out.println(processBuilder.environment()); //processBuilder.command("ping","127.0.0.1"); processBuilder.command("ipconfig","/all"); //將標(biāo)準(zhǔn)輸入流和錯(cuò)誤輸入流合并,通過標(biāo)準(zhǔn)輸入流讀取信息 processBuilder.redirectErrorStream(true); try { //啟動(dòng)進(jìn)程 Process start = processBuilder.start(); //獲取輸入流 InputStream inputStream = start.getInputStream(); //轉(zhuǎn)成字符輸入流 InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "gbk"); int len = -1; char[] c = new char[1024]; StringBuffer outputString = new StringBuffer(); //讀取進(jìn)程輸入流中的內(nèi)容 while ((len = inputStreamReader.read(c)) != -1) { String s = new String(c, 0, len); outputString.append(s); System.out.print(s); } inputStream.close(); } catch (IOException e) { e.printStackTrace(); } }
public static void main(String[] args) throws IOException { ProcessBuilder processBuilder = new ProcessBuilder("cmd","/c","dir"); processBuilder.directory(new File("D:/")); Process process = processBuilder.start(); BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream(), "GBK")); String line; while ((line = br.readLine()) != null) { System.out.println(line); } }
到此這篇關(guān)于Java中的ProcessBuilder類詳細(xì)解析的文章就介紹到這了,更多相關(guān)Java的ProcessBuilder類內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java8新特性之Collectors.joining()實(shí)例詳解
在項(xiàng)目中我們常常要對list集合的數(shù)據(jù)做一些字符串拼接/處理等相關(guān)操作,下面這篇文章主要給大家介紹了關(guān)于Java8新特性之Collectors.joining()的相關(guān)資料,需要的朋友可以參考下2023-01-01mybatis-plus常用注解@TableId和@TableField的用法
本文主要介紹了mybatis-plus常用注解@TableId和@TableField的用法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-04-04Spring框架基于AOP實(shí)現(xiàn)簡單日志管理步驟解析
這篇文章主要介紹了Spring框架基于AOP實(shí)現(xiàn)簡單日志管理步驟解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-06-06Springboot搭建JVM監(jiān)控(Springboot + Prometheus +&n
在應(yīng)用開發(fā)時(shí),監(jiān)控報(bào)警必不可少,本文主要介紹了Springboot搭建JVM監(jiān)控(Springboot + Prometheus + Grafana),具有一定的參考價(jià)值,感興趣的可以了解一下2024-05-05分析JVM源碼之Thread.interrupt系統(tǒng)級(jí)別線程打斷
在java編程中,我們經(jīng)常會(huì)調(diào)用Thread.sleep()方法使得線程停止運(yùn)行一段時(shí)間,而Thread類中也提供了interrupt方法供我們?nèi)ブ鲃?dòng)打斷一個(gè)線程。那么線程掛起和打斷的本質(zhì)究竟是什么,本文就此問題作一個(gè)探究2021-06-06SpringCloud集成zookeeper實(shí)現(xiàn)服務(wù)注冊并訪問功能
zookeeper和eureka一樣,是用于充當(dāng)服務(wù)注冊功能服務(wù)器的一個(gè)springcloud插件,這篇文章主要介紹了SpringCloud集成zookeeper實(shí)現(xiàn)服務(wù)注冊并訪問,需要的朋友可以參考下2022-06-06Java DriverManager.getConnection()獲取數(shù)據(jù)庫連接
這篇文章主要介紹了Java DriverManager.getConnection()獲取數(shù)據(jù)庫連接,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01