J2SE 5.0 引入 ProcessBuilder 類別,提供比 Runtime.exec() 更靈活、更物件導向的外部程式執行方式。本文透過實際範例示範如何使用 ProcessBuilder 在 Windows 環境下執行 ipconfig /all 並解析輸出以取得實體網卡 MAC 位址。
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<>();
try {
// 使用 ProcessBuilder 建立並啟動程序
p = new ProcessBuilder("ipconfig", "/all").start();
} catch (IOException e) {
return address;
}
// 讀取程序輸出
byte[] buffer = new byte[1024];
StringBuilder sb = new StringBuilder();
try (InputStream in = p.getInputStream()) {
int len;
while ((len = in.read(buffer)) > 0) {
sb.append(new String(buffer, 0, len));
}
} catch (IOException e) {
// 忽略讀取錯誤
}
// 解析輸出取得 Physical Address
String output = sb.toString();
String keyword = "Physical Address. . . . . . . . . :";
int idx = output.indexOf(keyword);
while (idx >= 0) {
output = output.substring(idx + keyword.length());
// MAC 位址長度為 17 字元(含冒號),這裡取 18 字元以防萬一
if (output.length() >= 17) {
address.add(output.substring(0, 17).trim());
}
idx = output.indexOf(keyword);
}
return address;
}
public static void main(String[] args) {
List<String> addresses = getPhysicalAddress();
for (String addr : addresses) {
System.out.printf("物理網卡地址: %s%n", addr);
}
}
}
// 可變參數傳遞指令與引數
ProcessBuilder pb = new ProcessBuilder("ipconfig", "/all");
// 或使用 List
// List<String> cmd = Arrays.asList("ipconfig", "/all");
// ProcessBuilder pb = new ProcessBuilder(cmd);
// 可設定環境變數
// pb.environment().put("MY_VAR", "value");
// 可設定工作目錄
// pb.directory(new File("C:/temp"));
Process process = pb.start();
try-with-resources(JDK 7+)自動關閉流。new String(buffer, 0, len) 避免殘留資料。errorStream 防止緩衝區滿導致阻塞。範例針對 Windows ipconfig 輸出格式解析。Linux/Mac 環境下應改用 ifconfig 或 ip link,並調整關鍵字與解析邏輯。
ProcessBuilder 以清晰的 API、豐富的配置選項取代了笨重的 Runtime.exec(),是 Java 執行外部程式的現代首選方案。