J2SE 5.0 引入的 ProcessBuilder 類別提供了更靈活的外部程式執行機制,相較於傳統的 Runtime.exec(),它支援環境變數設定、工作目錄指定、輸入輸出流重導向等進階功能。本文示範如何利用此新特性在 Windows 環境下擷取網卡實體位址(MAC Address)。
package com.kuaff.jdk5package;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
public class ProcessBuilderShow {
public static List<String> getPhysicalAddress() {
Process p = null;
List<String> address = new ArrayList<String>();
try {
// 執行 ipconfig /all 取得完整網路設定
p = new ProcessBuilder("ipconfig", "/all").start();
} catch (IOException e) {
return address; // 發生例外回傳空列表
}
byte[] buffer = new byte[1024];
StringBuffer output = new StringBuffer();
InputStream in = p.getInputStream();
try {
int bytesRead;
while ((bytesRead = in.read(buffer)) > 0) {
output.append(new String(buffer, 0, bytesRead));
}
} catch (IOException e1) {
// 忽略讀取錯誤
} finally {
try { in.close(); } catch (IOException e2) {}
}
// 解析輸出文字擷取 MAC 位址
String result = output.toString();
String keyword = "Physical Address. . . . . . . . . :";
int index = result.indexOf(keyword);
while (index > 0) {
result = result.substring(index + keyword.length());
// MAC 位址格式為 XX-XX-XX-XX-XX-XX(17 字元含連字號)
address.add(result.substring(0, 17).trim());
index = result.indexOf(keyword);
}
return address;
}
public static void main(String[] args) {
List<String> addresses = ProcessBuilderShow.getPhysicalAddress();
for (String addr : addresses) {
System.out.printf("實體網卡位址: %s%n", addr);
}
}
}
getInputStream() 避免緩衝區滿導致子程式掛起ipconfig 輸出為 Big5/CP950 編碼,實際專案應指定 new String(buffer, 0, bytesRead, "MS950")ifconfig 或 ip link 指令,關鍵字對應修改為 "ether" 或 "HWaddr"getErrorStream() 避免死結,或使用 redirectErrorStream(true) 合併標準錯誤輸出Pattern.compile("([0-9A-F]{2}[:-]){5}[0-9A-F]{2}") 更健壯地提取 MAC 位址CompletableFuture 實作非阻塞式網路資訊收集ProcessBuilder 作為 Java 5 引入的重要改進,不僅解決了 Runtime.exec 的諸多限制,更為系統整合開發提供了標準化、可擴展的外部程式呼叫框架。掌握其用法對於開發跨平台系統管理工具具有重要價值。