1. 程式人生 > >JDK5.0新特性系列---7.使用ProcessBuilder執行本地命令

JDK5.0新特性系列---7.使用ProcessBuilder執行本地命令

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();
       }
}