面试题:如何在 Java 中调用外部可执行程序或系统命令?

在 Java 中,可以使用 java.lang.Runtime 类或 java.lang.ProcessBuilder 类来调用外部可执行程序或系统命令。这两种方式都可以执行系统命令、启动外部程序,并获取其输入输出流和退出码。


✅ 推荐方式:使用 ProcessBuilder(更灵活、安全、现代)

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

public class RunExternalCommand {
    public static void main(String[] args) {
        try {
            // 构建命令,例如:Windows 上执行 ipconfig,Linux/macOS 上执行 ls -l
            ProcessBuilder processBuilder = new ProcessBuilder("ipconfig"); // Windows 示例
            // ProcessBuilder processBuilder = new ProcessBuilder("ls", "-l"); // Linux/macOS 示例

            // 将错误流合并到标准输出流
            processBuilder.redirectErrorStream(true);

            // 启动进程
            Process process = processBuilder.start();

            // 读取命令输出
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }

            // 获取退出码
            int exitCode = process.waitFor();
            System.out.println("Exited with code " + exitCode);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

❗传统方式:使用 Runtime.getRuntime().exec()

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

public class RunExternalCommandOld {
    public static void main(String[] args) {
        try {
            // 执行命令
            Process process = Runtime.getRuntime().exec("ipconfig"); // Windows 示例
            // Process process = Runtime.getRuntime().exec("ls -l"); // Linux/macOS 示例

            // 读取输出
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }

            // 等待进程结束并获取退出码
            int exitCode = process.waitFor();
            System.out.println("Exited with code " + exitCode);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

⚠️ 注意事项

项目说明
安全性执行外部命令可能带来安全风险,特别是在处理用户输入时,应防止命令注入攻击。执行外部命令可能带来安全风险,特别是在处理用户输入时,应防止命令注入攻击。执行外部命令可能带来安全风险,特别是在处理用户输入时,应防止命令注入攻击。
跨平台兼容性不同操作系统支持的命令不同,例如 ipconfig(Windows) vs ifconfigip addr(Linux)。
阻塞问题如果命令输出较多,建议及时读取输出流,否则可能导致进程阻塞或死锁。
错误流处理建议同时读取 process.getErrorStream(),避免缓冲区满导致程序挂起。

✅ 总结

方法优点缺点
ProcessBuilder更现代、线程安全、可配置性强稍微复杂一点
Runtime.exec()简单、传统方式不够灵活,容易出错

💡 面试建议:

  • 说明两种方式,并推荐使用 ProcessBuilder
  • 强调异常处理和流的读取的重要性
  • 提到跨平台兼容性和安全性问题

如果你在项目中需要执行外部命令,比如执行脚本、调用 Python 程序、执行系统命令等,使用 ProcessBuilder 是首选方式。

THE END
喜欢就支持一下吧
点赞7 分享