訪問平台專有的信息並不是一件容易的事
雖然可以使用 Runtime
exec() 創建進程
但由於平台之間的差異
構造參數集常常令人頭痛不已
此外
System 的 getenv() 方法從開始進行 Java 編程就遭到反對
什麼時候一個遭到反對的方法不再被反對呢?使用 System 的 getenv() 方法時就會遇到這種情況
Tiger 以
年正式發布之前的 Java 平台為基礎
它沒有拋棄該方法
同時還提供了一個新的類 ProcessBuilder (屬於包 java
lang )
用它來創建進程並與系統進程交互
訪問環境變量 雖然我個人並不想退回到原來使用 AWT 組件的事件模型
但是早期的 Java 平台版本(稱為 alpha 版)有一個很好的特性
即能夠訪問環境變量
該方法和當時
編寫一次
隨處運行
的頌詞背道而馳
因此當 Java 平台發布
版時
System 的 getenv() 方法受到了抨擊
雖然
版為何拋棄原來的一些內容一直令我迷惑不解
但我常常看到該方法引起新入門開發人員的興趣
時間回到
年
您現在終於能夠使用這個方法了
如清單
所示
該方法的使用很簡單
清單
調用 getenv
public class EnvTest {
public static void main(String args[]) {
System
out
println(System
getenv(args[
]));
}
}
只要在命令行中隨 getenv 調用傳入變量的名稱
就可以得到它的當前值
比如在我那台用了兩年的桌面機上
如果輸入參數 PROCESSOR_IDENTIFIER
就會得到清單
所示的結果
清單
getenv 的輸出結果
java EnvTest PROCESSOR_IDENTIFIER
x
Family
Model
Stepping
GenuineIntel
首先要注意的是方法名 getenv()
它完全采用小寫形式
而不是采用您所預料的大小寫混合形式( getEnv() )
這是因為在正式發布之前的最初命名方法就是這樣的
其次
訪問環境變量常常要使用平台專用的代碼
如果確實希望這樣做也可以
但這樣就偏離了百分之百的純 Java 模型
上述代碼本身仍然是純粹的 Java 代碼
因此使用該方法並不完全違背這一原則
但是使用了這麼多年的系統屬性之後
使用 getenv() 感覺怪怪的
Tiger 提供了兩個版本的 getenv() 方法
而不是一個
第二個版本返回與系統中當前設置的所有環境變量對應的
名/值
對(name
value pairs)
清單
說明了這種新方法的應用
並打印出了所有環境變量的鍵和值
清單
訪問所有的環境變量
import java
util
Map;
public class EnvDump {
public static void main(String args[]) {
for (Map
Entry entry: System
getenv()
entrySet()) {
System
out
println(entry
getKey() +
/
+
entry
getValue());
}
}
}
理解 ProcessBuilder 這為我們帶來了一個新的類 java
lang
ProcessBuilder
平台的早期版本允許通過 Runtime 類的 exec() 方法創建本機進程
該方法仍然有效
但是因為能以 String 數組作為參數
以 File 參數作為工作目錄
所以用這種方法定制子進程比較困難
使用 ProcessBuilder 可以簡化這個過程
它提供了 directory(File) 方法來改變進程的工作目錄
可以用 environment() 方法在進程空間中添加和刪除環境變量
清單
說明了 ProcessBuilder 的一種簡單用法
它使用 ipconfig 命令獲得 Internet 配置信息
該方法適用於多數平台
否則可以將 ipconfig 改寫成所用平台上的工作命令
啟動進程構造程序之後
需要獲得其 InputStream
以讀入所創建進程的結果
清單
使用 ProcessBuilder
import java
io
*;
public class ProcessTest {
public static void main(String args[]) throws IOException {
Process p = new ProcessBuilder(
ipconfig
)
start();
InputStream is = p
getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line;
while ((line = br
readLine()) != null) {
System
out
println(line);
}
}
}
如清單
所示
該程序的運行結果與在命令行中執行 ipconfig 所得到的結果類似(您得到的結果看起來可能有所不同)
清單
ProcessBuilder 的輸出結果
Windows
IP Configuration
Ethernet adapter Local Area Connection:
Connection
specific 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 還提供了一種創建本機進程的簡單方法
應該用它來代替所有過時的 Runtime
exec() 調用
開始重構吧!
From:http://tw.wingwit.com/Article/program/Java/hx/201311/26897.html