Java 的跨平台特性使其難以直接訪問底層硬體資訊。在軟體授權綁定、設備指紋識別等場景下,獲取網卡 MAC 地址是常見需求。本文介紹在 Windows XP/NT/2000 環境下,透過 Runtime.exec() 執行系統命令 ipconfig /all 並解析輸出流,以純 Java 方式獲取 MAC 地址的完整實現方案。
每個 Java 應用擁有唯一的 Runtime 實例,透過 Runtime.getRuntime() 獲取。其 exec(String command) 方法可啟動子進程執行外部命令,返回 Process 物件用於控制進程與獲取 I/O 流。
封裝原生進程,關鍵方法:
getInputStream():獲取進程標準輸出流getErrorStream():獲取進程錯誤輸出流waitFor():阻塞等待進程結束,返回退出碼注意: 若命令輸出較多,緩衝區可能填滿導致進程阻塞,必須在 waitFor() 前讀取輸出流。
ipconfig /all 輸出格式典型輸出片段:
Ethernet adapter Local Area Connection:
Physical Address. . . . . . . . . : 00-10-DC-A9-0B-2C
目標行特徵:包含 Physical Address 關鍵字,冒號後為 MAC 地址。
Process process = Runtime.getRuntime().exec("cmd /c ipconfig /all");
BufferedReader reader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
if (line.indexOf("Physical Address") != -1) {
int colonIndex = line.indexOf(":");
if (colonIndex != -1) {
String mac = line.substring(colonIndex + 2).trim();
// 進一步驗證格式:XX-XX-XX-XX-XX-XX
return mac;
}
}
}
process.waitFor();
ReadMACimport java.io.*;
public class ReadMAC {
public static String checkPhysicalAddress() {
String physicalAddress = "read MAC error!";
try {
String line;
Process process = Runtime.getRuntime().exec("cmd /c ipconfig /all");
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
while ((line = bufferedReader.readLine()) != null) {
if (line.indexOf("Physical Address") != -1) {
int colonPos = line.indexOf(":");
if (colonPos != -1) {
physicalAddress = line.substring(colonPos + 2).trim();
break; // 找到第一張網卡即返回
}
}
}
process.waitFor();
} catch (Exception e) {
e.printStackTrace();
}
return physicalAddress;
}
public static void main(String[] args) {
System.out.println("本機 MAC 地址:" + checkPhysicalAddress());
}
}
本機 MAC 地址:00-10-DC-A9-0B-2C
本方案依賴 Windows ipconfig 命令輸出格式,不具備跨平台性。移植至其他作業系統需修改:
| 作業系統 | 命令 | 關鍵字 |
|---|---|---|
| Linux/Unix | ifconfig -a 或 ip link show | ether / link/ether |
| macOS | ifconfig en0 | ether |
| Windows (新版) | getmac /v /fo list | Physical Address |
建議採用策略模式封裝不同平台的解析器,運行時根據 System.getProperty("os.name") 動態選擇。
利用 Runtime.exec() 執行系統命令並解析輸出流,是 Java 訪問平台特有資訊的通用橋接手段。雖非純跨平台方案,但在特定環境下開發部署可控的內部系統時,該方法簡單可靠、無需 JNI/JNA 複雜依賴,極具工程實用價值。