熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java核心技術 >> 正文

馴服Tiger之訪問環境變量和調用子進程

2013-11-23 19:27:26  來源: Java核心技術 

  訪問平台專有的信息並不是一件容易的事雖然可以使用 Runtimeexec() 創建進程但由於平台之間的差異構造參數集常常令人頭痛不已此外 System 的 getenv() 方法從開始進行 Java 編程就遭到反對
  
  什麼時候一個遭到反對的方法不再被反對呢?使用 System 的 getenv() 方法時就會遇到這種情況Tiger 以 年正式發布之前的 Java 平台為基礎它沒有拋棄該方法同時還提供了一個新的類 ProcessBuilder (屬於包 javalang )用它來創建進程並與系統進程交互
  
  訪問環境變量
  
  雖然我個人並不想退回到原來使用 AWT 組件的事件模型但是早期的 Java 平台版本(稱為 alpha 版)有一個很好的特性即能夠訪問環境變量該方法和當時編寫一次隨處運行的頌詞背道而馳因此當 Java 平台發布 版時 System 的 getenv() 方法受到了抨擊雖然 版為何拋棄原來的一些內容一直令我迷惑不解但我常常看到該方法引起新入門開發人員的興趣時間回到 您現在終於能夠使用這個方法了如清單 所示該方法的使用很簡單
  
  清單 調用 getenv
  
  public class EnvTest {
  public static void main(String args[]) {
  Systemoutprintln(Systemgetenv(args[]));
  }
  }
  
  只要在命令行中隨 getenv 調用傳入變量的名稱就可以得到它的當前值比如在我那台用了兩年的桌面機上如果輸入參數 PROCESSOR_IDENTIFIER 就會得到清單 所示的結果
  
  清單 getenv 的輸出結果
  
  java EnvTest PROCESSOR_IDENTIFIER
  x Family Model Stepping GenuineIntel
  
  首先要注意的是方法名 getenv() 它完全采用小寫形式而不是采用您所預料的大小寫混合形式( getEnv() )這是因為在正式發布之前的最初命名方法就是這樣的其次訪問環境變量常常要使用平台專用的代碼如果確實希望這樣做也可以但這樣就偏離了百分之百的純 Java 模型上述代碼本身仍然是純粹的 Java 代碼因此使用該方法並不完全違背這一原則但是使用了這麼多年的系統屬性之後使用 getenv() 感覺怪怪的
  
  Tiger 提供了兩個版本的 getenv() 方法而不是一個第二個版本返回與系統中當前設置的所有環境變量對應的名/值對(namevalue pairs)清單 說明了這種新方法的應用並打印出了所有環境變量的鍵和值
  
  清單 訪問所有的環境變量
  
  import javautilMap;
  
  public class EnvDump {
  public static void main(String args[]) {
  for (MapEntry entry: Systemgetenv()entrySet()) {
  Systemoutprintln(entrygetKey() + / +
  entrygetValue());
  }
  }
  }
  
  理解 ProcessBuilder
  
  這為我們帶來了一個新的類 javalangProcessBuilder 平台的早期版本允許通過 Runtime 類的 exec() 方法創建本機進程該方法仍然有效但是因為能以 String 數組作為參數以 File 參數作為工作目錄所以用這種方法定制子進程比較困難使用 ProcessBuilder 可以簡化這個過程它提供了 directory(File) 方法來改變進程的工作目錄可以用 environment() 方法在進程空間中添加和刪除環境變量清單 說明了 ProcessBuilder 的一種簡單用法它使用 ipconfig 命令獲得 Internet 配置信息該方法適用於多數平台否則可以將 ipconfig 改寫成所用平台上的工作命令啟動進程構造程序之後需要獲得其 InputStream 以讀入所創建進程的結果
  
  清單 使用 ProcessBuilder
  
  import javaio*;
  
  public class ProcessTest {
  public static void main(String args[]) throws IOException {
  Process p = new ProcessBuilder(ipconfig)start();
  InputStream is = pgetInputStream();
  BufferedReader br = new BufferedReader(new InputStreamReader(is));
  String line;
  while ((line = brreadLine()) != null) {
  Systemoutprintln(line);
  }
  }
  }
  
  如清單 所示該程序的運行結果與在命令行中執行 ipconfig 所得到的結果類似(您得到的結果看起來可能有所不同)
  
  清單 ProcessBuilder 的輸出結果
  
  Windows IP Configuration
  
  Ethernet adapter Local Area Connection:
  
  Connectionspecific DNS Suffix :
  IP Address :
  Subnet Mask :
  Default Gateway :
  
  如前所述 ProcessBuilder 類不僅能生成新的進程而且還能獲得其結果在調用其 start() 方法之前還可以調整進程所執行的上下文如果不喜歡環境變量您可以使用 environment 獲得當前設置並調用 clear() 清除映射如果需要添加環境變量可以調用 environment 獲得當前設置然後通過 put(name value) 添加新的變量如果希望使用新的工作目錄可以調用 directory() 並提供新的工作目錄作為 File 對象就是這麼簡單使用表示將運行的命令及其參數的數目可變的字符串參數來創建 ProcessBuilder 一旦使用新的環境變量和工作目錄配置 ProcessBuilder 就可以調用 start() 來執行命令
  
  結束語
  
  您希望您所喜歡的方法在遭到反對之後再受到歡迎嗎?當然有時候一個受到抨擊的方法雖然從沒在 Java 發行版本中受到真正的支持但它可能重新獲得新生只要有足夠多的用戶在 Sun 的 Bug Parade 上呼吁和投票開發人員就可以改變 Java 平台的演進方向雖然我曾懷疑過時的 AWT 事件模型會卷土重來——盡管每個人都這樣要求但只是一些簡單的問題(如訪問環境變量)最終得到了 Java 平台的支持小心地使用它除了反對 getenv 的問題之外 ProcessBuilder 還提供了一種創建本機進程的簡單方法應該用它來代替所有過時的 Runtimeexec() 調用開始重構吧!
From:http://tw.wingwit.com/Article/program/Java/hx/201311/26897.html
  • 上一篇文章:

  • 下一篇文章:
  • 推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.