首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 獲取 MAC 地址的實用方法與跨平台考量

     編輯:Java 相關知識

前言

在 Java 開發中,獲取網卡的 MAC 地址是常見需求,無論是用於軟體授權綁定、設備識別還是網路診斷。然而,Java 標準庫並未提供直接、跨平台的 API 來取得 MAC 地址。本文將介紹一種在 Windows 環境下透過執行系統命令 ipconfig /all 並解析輸出來獲取 MAC 地址的經典做法,同時探討其局限性與現代替代方案。

核心實作:呼叫系統命令解析輸出

以下程式碼示範如何在 Windows 上啟動 ipconfig /all 進程,讀取其標準輸出流,並從包含 "Physical Address" 的行中提取 MAC 地址:

package com.example.network;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class MacAddressUtil {

    /**
     * 獲取本機第一張網卡的 MAC 地址 (僅限 Windows)
     * @return MAC 地址字串,若失敗則返回空字串
     */
    public static String getMacAddress() {
        String address = "";
        String os = System.getProperty("os.name");
        System.out.println("作業系統: " + os);

        // 僅在 Windows 上嘗試此方法
        if (os != null && os.startsWith("Windows")) {
            try {
                ProcessBuilder pb = new ProcessBuilder("ipconfig", "/all");
                Process process = pb.start();

                try (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) {
                                address = line.substring(colonIndex + 1).trim();
                                break; // 取第一個找到的即可
                            }
                        }
                    }
                }
                return address;
            } catch (IOException e) {
                System.err.println("執行 ipconfig 失敗: " + e.getMessage());
            }
        }
        return address;
    }

    public static void main(String[] args) {
        String mac = getMacAddress();
        System.out.println("獲取到的 MAC 地址: " + mac);
    }
}

程式碼解析

  • ProcessBuilder:比舊版 Runtime.exec() 更靈活,支援參數列表傳遞,避免命令注入風險。
  • 輸出流讀取:必須在獨立執行緒或同步讀取進程的輸出/錯誤流,否則緩衝區滿會導致進程掛起。
  • 字串解析:ipconfig /all 輸出格式隨系統語言不同而異(中文為「實體地址」,英文為「Physical Address」),實際部署需處理多語言情況。

跨平台與現代化替代方案

上述方法強依賴 Windows 命令列,無法在 Linux/macOS 上運作。現代 Java (JDK 9+) 建議使用 java.net.NetworkInterface API 實現跨平台獲取:

import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Enumeration;

public static String getMacAddressModern() {
    try {
        Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
        while (interfaces.hasMoreElements()) {
            NetworkInterface ni = interfaces.nextElement();
            // 過濾掉回環、虛擬、未啟用的介面
            if (!ni.isLoopback() && ni.isUp() && !ni.isVirtual()) {
                byte[] macBytes = ni.getHardwareAddress();
                if (macBytes != null) {
                    StringBuilder sb = new StringBuilder();
                    for (int i = 0; i < macBytes.length; i++) {
                        sb.append(String.format("%02X%s", macBytes[i], (i < macBytes.length - 1) ? "-" : ""));
                    }
                    return sb.toString();
                }
            }
        }
    } catch (SocketException e) {
        e.printStackTrace();
    }
    return "";
}

總結

雖然執行系統命令是早期 Java 獲取 MAC 地址的常用手段,但存在平台鎖定、語言敏感、權限需求等缺點。現代專案應優先使用 NetworkInterface API,僅在舊版 JDK 或特殊環境下才考慮命令列備案。開發時請務必處理多網卡、虛擬網卡(如 Docker、VPN)導致的多 MAC 地址場景,根據業務邏輯選擇合適的網卡綁定策略。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved