JDK5.0新特性系列---7.使用ProcessBuilder執行本地命令
阿新 • • 發佈:2019-02-15
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import java.util.List; import java.util.Map; /** * 在J2SE5.0之前使用Runtime的exec方法執行本地命令. * 在J2Se5.0之後,可以使用ProcessBuilder執行本地命令 * 它提供的功能更加豐富,能夠設定設定工作目錄、環境變數等 * 本例PorcessBuilder執行Windows作業系統的"ipconfig/all"命令,獲取本機網絡卡的MAC地址 */ /**關鍵技術剖析 * 用本命令名和命令的引數選項構造ProcessBuilder物件,它的start方法執行命令,啟動一個程序,返回一個Process物件 * ProcessBuilder的environment方法獲得執行程序的環境變數,得到一個Map,可以修改環境變數 * ProcessBuilder的directory方法切換工作目錄 * Process的getInputStream方法獲得程序的標準輸出流,getErrorStream方法獲得程序的錯誤輸出流 */ public class UsingProcessBuilder { /**獲取Windows系統下的網絡卡的MAC地址*/ public static List<String> getPhysicalAddress(){ Process p = null; List<String> address = new ArrayList<String>(); //物理網絡卡列表 try{ p = new ProcessBuilder("ipconfig","/all").start(); //執行ipconfig/all命令 }catch(IOException e){ return address; } byte[] b = new byte[1024]; int readbytes = -1; StringBuffer sb = new StringBuffer(); //讀取程序輸出值 //在JAVA IO中,輸入輸出是針對JVM而言,讀寫是針對外部資料來源而言 InputStream in = p.getInputStream(); try{ while((readbytes = in.read(b)) != -1){ sb.append(new String(b,0,readbytes)); } }catch(IOException e1){ }finally { try{ in.close(); }catch (IOException e2){ } } //以下是分析輸出值,得到物理網絡卡 String rtValue = sb.toString(); int i = rtValue.indexOf("Physical Address. . . . . . . . . :"); while (i > 0){ rtValue = rtValue.substring(i + "Physical Address. . . . . . . . . :".length()); address.add(rtValue.substring(1,18)); i = rtValue.indexOf("Physical Address. . . . . . . . . :"); } return address; } /**執行自定義的一個命令,該命令放在C:/temp下,並且需要兩個環境變數的支援*/ public static boolean executeMyCommand1(){ //建立系統程序建立器 ProcessBuilder pb = new ProcessBuilder("myCommand","myArg1","myArg2"); Map<String, String> env = pb.environment(); //獲得程序的環境 //設定和去除環境變數 env.put("VAR1", "myValue"); env.remove("VAR0"); env.put("VAR2", env.get("VAR1") + ";"); //迭代環境變數,獲取屬性名和屬性值 Iterator it=env.keySet().iterator(); String sysatt = null; while(it.hasNext()) { sysatt = (String)it.next(); System.out.println("System Attribute:"+sysatt+"="+env.get(sysatt)); } pb.directory(new File("C:/temp")); try{ Process p = pb.start(); //得到程序例項 //等待程序執行完畢 if(p.waitFor() != 0){ //如果程序執行結果不為0,表示程序是錯誤退出的 //獲得程序例項的錯誤輸出 InputStream error = p.getErrorStream(); //do something } InputStream sdin = p.getInputStream(); //獲得程序例項的標準輸出 //do something }catch(IOException e){ }catch(InterruptedException e){ } return true; } public static void executeMyCommand2(){ ProcessBuilder pb = null; String sysatt = null; try { //建立一個程序示例 pb = new ProcessBuilder("cmd.exe"); //獲取系統引數並列印顯示 Map<String, String> env = pb.environment(); Iterator it=env.keySet().iterator(); while(it.hasNext()) { sysatt = (String)it.next(); System.out.println("System Attribute:"+sysatt+"="+env.get(sysatt)); } //設定工作目錄 pb.directory(new File("d://myDir")); Process p = pb.start(); //將要執行的Windows命令寫入 BufferedWriter bw=new BufferedWriter(newOutputStreamWriter(p.getOutputStream())); //'/r/n'是必須寫入的 bw.write("test.bat /r/n"); bw.write("ping -t www.yahoo.com.cn /r/n"); //flush()方法是必須呼叫的 bw.flush(); //將執行結果列印顯示 InputStream is = p.getInputStream(); InputStreamReader isr = new InputStreamReader(is, "GBK"); BufferedReader br = new BufferedReader(isr); String line; while ((line = br.readLine()) != null) { System.out.println(line); } } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args){ List<String> address = UsingProcessBuilder.getPhysicalAddress(); for(String add : address){ System.out.printf("物理網絡卡地址: %s%n",add); } executeMyCommand1(); executeMyCommand2(); } }