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

Java 調用外部程式:Runtime.exec() 與 ProcessBuilder 實戰

     編輯:Java 相關知識

基礎用法:Runtime.exec()

public class RuntimeExecDemo {
    public static void main(String[] args) {
        try {
            // Windows 路徑需雙反斜杠或正斜杠
            String cmd = "C:/Program Files/Microsoft Visual Studio/Common/MSDev98/Bin/MSDEV.EXE";
            Process process = Runtime.getRuntime().exec(cmd);
            // 可選:等待結束、獲取退出碼
            int exitCode = process.waitFor();
            System.out.println("進程退出碼: " + exitCode);
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }
}

進階用法:ProcessBuilder (推薦 JDK 5+)

ProcessBuilder pb = new ProcessBuilder("notepad.exe", "readme.txt");
pb.directory(new File("C:/workspace"));        // 工作目錄
pb.environment().put("MY_VAR", "value");       // 環境變量
pb.redirectErrorStream(true);                  // 合併錯誤流到標準輸出
Process process = pb.start();

// 異步讀取輸出流 (防阻塞)
try (BufferedReader reader = new BufferedReader(
        new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8))) {
    String line;
    while ((line = reader.readLine()) != null) {
        System.out.println(line);
    }
}
int exitCode = process.waitFor();

關鍵坑點與對策

問題原因解決方案
進程掛起/死鎖輸出/錯誤流緩衝區填滿,子進程寫入阻塞**必須**在單獨線程中讀取 getInputStream() 和 getErrorStream(),或 redirectErrorStream(true)
路徑含空格失效命令字符串解析錯誤使用 ProcessBuilder 列表形式傳參,或嚴格引用
中文亂碼系統默認編碼與控制台不一致顯式指定 InputStreamReader(stream, "GBK") 或 StandardCharsets.UTF_8
權限不足目標程式需管理員權限簽名 JAR、配置 UAC、或使用 JNA/JNI 調用 ShellExecuteEx

最佳實踐清單

  1. 優先 ProcessBuilder,參數列表化、環境隔離、重定向靈活。
  2. 異步消費流:啟動兩個守護線程分別讀取 stdout/stderr,或使用 Apache Commons Exec / ProcessHandle (JDK 9+) 簡化。
  3. 設置合理 超時機制:process.waitFor(timeout, TimeUnit.SECONDS) (JDK 8+)。
  4. 捕獲 exitCode 判斷成敗,非 0 視為異常。
  5. 跨平台命令抽象:Windows cmd /c、Linux sh -c。

安全警示

避免拼接用戶輸入構造命令 (命令注入風險)。若必須動態參數,使用 ProcessBuilder 列表形式,參數不經 Shell 解析。

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