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

J2SE 5.0 ProcessBuilder 實戰:靈活啟動外部進程與獲取網卡 MAC 地址

     編輯:Java 相關知識

為什麼選擇 ProcessBuilder?

對比 Runtime.exec(),ProcessBuilder 提供:

  • 命令與參數列表化,避免字符串解析歧義
  • 環境變量精確控制 (environment() 返回可修改 Map)
  • 工作目錄設置 (directory(File))
  • 輸入/輸出/錯誤流重定向 (redirectInput/Output/Error)

核心 API 速覽

ProcessBuilder pb = new ProcessBuilder("ipconfig", "/all"); // Windows
// ProcessBuilder pb = new ProcessBuilder("ifconfig", "-a"); // Linux/Mac
pb.directory(new File("C:/work"));        // 設置工作目錄
Map env = pb.environment(); // 獲取環境變量副本
env.put("MY_VAR", "value");               // 修改環境變量
Process process = pb.start();             // 啟動進程

實戰案例:Windows 獲取物理網卡 MAC 地址

package com.kuaff.jdk5package;
import java.io.*;
import java.util.*;

public class ProcessBuilderShow {
    public static List getPhysicalAddress() {
        List address = new ArrayList<>();
        Process p;
        try {
            p = new ProcessBuilder("ipconfig", "/all").start();
        } catch (IOException e) {
            return address;
        }

        // 讀取進程輸出
        StringBuilder sb = new StringBuilder();
        try (InputStream in = p.getInputStream()) {
            byte[] buf = new byte[1024];
            int len;
            while ((len = in.read(buf)) > 0) {
                sb.append(new String(buf, 0, len));
            }
        } catch (IOException ignored) {}

        // 解析輸出提取 MAC
        String output = sb.toString();
        String keyword = "Physical Address. . . . . . . . . :";
        int idx = output.indexOf(keyword);
        while (idx > 0) {
            output = output.substring(idx + keyword.length());
            String mac = output.substring(0, 17).trim(); // 格式: XX-XX-XX-XX-XX-XX
            if (mac.matches("([0-9A-Fa-f]{2}[:-]){5}[0-9A-Fa-f]{2}")) {
                address.add(mac);
            }
            idx = output.indexOf(keyword);
        }
        return address;
    }

    public static void main(String[] args) {
        for (String mac : getPhysicalAddress()) {
            System.out.printf("物理網卡地址: %s%n", mac);
        }
    }
}

關鍵點解析

  • 命令列表化:new ProcessBuilder("ipconfig", "/all") 避免空格/引號轉義問題
  • 流讀取:使用 try-with-resources (Java 7+) 或標準循環確保流關閉
  • 編碼處理:Windows 控制台默認 GBK,生產環境建議指定 new String(buf, 0, len, "GBK")
  • 正則校驗:過濾非標準 MAC 格式(如隧道適配器的 00-00-00-00-00-00)
  • 跨平台:Linux 用 ifconfig/ip link,Mac 用 ifconfig,解析邏輯需適配

進階用法:異步處理與管道

// 異步讀取輸出,避免緩衝區填滿導致進程阻塞
new Thread(() -> {
    try (BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()))) {
        String line;
        while ((line = br.readLine()) != null) { /* 實時處理 */ }
    } catch (IOException e) { /* handle */ }
}).start();

// 進程管道:將進程 A 輸出直接作為進程 B 輸入 (Java 9+)
ProcessBuilder pb1 = new ProcessBuilder("cmd", "/c", "dir");
ProcessBuilder pb2 = new ProcessBuilder("findstr", ".java");
List processes = ProcessBuilder.startPipeline(List.of(pb1, pb2));

總結

ProcessBuilder 是 Java 5 引入的進程管理利器,以物件化設計替代字符串拼接,賦予開發者對環境、目錄、流的精細控制。結合流異步讀取與正則解析,可構建健壯的系統集成工具(如許可證檢測、硬件指纹採集、外部引擎調用)。

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