Java如何调用cmd命令行?

在Java中调用命令行,通常使用Runtime.getRuntime().exec()ProcessBuilder类执行CMD命令,通过创建Process对象获取输入/输出流,可读取命令结果并处理执行状态,需注意异常处理和资源释放。

核心方法:Runtime.exec()

Runtime.getRuntime().exec() 是Java早期提供的API,适用于简单命令调用。

Java如何调用cmd命令行?

基础示例

try {
    // 执行dir命令(Windows)或ls命令(Linux/Mac)
    Process process = Runtime.getRuntime().exec("cmd /c dir C:\");
    // 获取命令输出流
    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("Exit Code: " + exitCode);
} catch (IOException | InterruptedException e) {
    e.printStackTrace();
}

关键参数说明

  • cmd /c [命令]:Windows中/c表示执行后关闭cmd窗口。
  • 若命令含空格(如路径),需用数组传参避免解析错误:
    Process process = Runtime.getRuntime().exec(
        new String[]{"cmd", "/c", "echo", "Hello World!"}
    );

推荐方法:ProcessBuilder

ProcessBuilder(Java 5+)提供更灵活的参数控制、环境变量管理和流重定向。

基础示例

try {
    // 构建命令及参数
    ProcessBuilder builder = new ProcessBuilder(
        "cmd.exe", "/c", "ping", "www.baidu.com"
    );
    // 重定向错误流到标准输出(便于统一处理)
    builder.redirectErrorStream(true);
    // 启动进程
    Process process = builder.start();
    // 读取输出
    try (BufferedReader reader = new BufferedReader(
        new InputStreamReader(process.getInputStream())
    )) {
        String line;
        while ((line = reader.readLine()) != null) {
            System.out.println(line);
        }
    }
    // 检查执行结果
    int exitCode = process.waitFor();
    if (exitCode == 0) {
        System.out.println("命令执行成功!");
    } else {
        System.out.println("命令执行失败!Exit Code: " + exitCode);
    }
} catch (IOException | InterruptedException e) {
    e.printStackTrace();
}

进阶功能

  1. 设置工作目录
    builder.directory(new File("D:\project"));
  2. 环境变量管理
    Map<String, String> env = builder.environment();
    env.put("JAVA_HOME", "C:\Program Files\Java\jdk-17");
  3. 输出重定向到文件
    builder.redirectOutput(new File("output.log"));

注意事项与最佳实践

  1. 流处理必须完整
    未读取的输出流可能导致进程阻塞,始终处理getInputStream()(标准输出)和getErrorStream()(错误输出)。

  2. 超时控制
    使用waitFor(long timeout, TimeUnit unit)避免无限等待:

    Java如何调用cmd命令行?

    if (!process.waitFor(30, TimeUnit.SECONDS)) {
        process.destroy(); // 强制终止进程
    }
  3. 命令注入风险
    禁止直接拼接用户输入到命令中!应使用参数化传递:

    // 错误示例(高危!)
    String userInput = "malicious_command & rm -rf /";
    Runtime.getRuntime().exec("cmd /c " + userInput);
    // 正确做法
    ProcessBuilder builder = new ProcessBuilder("cmd", "/c", "safe-command", userInput);
  4. 跨平台兼容性

    • Windows:命令前缀cmd /c
    • Linux/Mac:使用/bin/sh -c或直接调用可执行文件
      String command = System.getProperty("os.name").toLowerCase().contains("win") 
                    ? "cmd /c dir" : "/bin/ls";
  5. 异常处理
    捕获IOException(命令不存在)和InterruptedException(进程中断)。

    Java如何调用cmd命令行?


Runtime与ProcessBuilder对比

特性 Runtime.exec() ProcessBuilder
参数灵活性 需手动处理空格和引号 支持参数列表(更安全)
环境变量控制 无直接支持 可通过environment()修改
工作目录设置 不支持 支持directory()
流重定向 需手动编码 内置redirectOutput()
适用场景 简单命令 复杂流程或生产环境

  • 简单命令:优先使用Runtime.exec(),注意参数格式。
  • 复杂任务:选择ProcessBuilder,尤其在需要环境控制、目录设置或流重定向时。
  • 安全第一:严格校验外部输入,避免命令注入漏洞。

通过合理选择API并遵循最佳实践,Java可高效安全地集成系统命令,适用于自动化部署、批处理等场景。


引用说明 参考Oracle官方文档:

原创文章,发布者:酷盾叔,转转请注明出处:https://www.kd.cn/ask/23101.html

(0)
酷盾叔的头像酷盾叔
上一篇 2025年6月13日 22:54
下一篇 2025年6月13日 22:58

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

联系我们

400-880-8834

在线咨询: QQ交谈

邮件:HI@E.KD.CN