java执行bat命令碰到的阻塞问题的解决方法


在Java中执行`.bat`批处理文件时,如果遇到了阻塞问题,通常是因为Java的`Runtime.getRuntime().exec()`方法或`ProcessBuilder`类在启动外部进程时没有正确地处理输入、输出和错误流。这些流在默认情况下是阻塞的,如果它们被填满而没有被读取,那么可能会导致Java程序挂起。

为了解决这个问题,你需要确保在启动`.bat`文件后,正确地读取这些流。以下是一个使用`ProcessBuilder`类来执行`.bat`文件并处理这些流的示例代码:


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

public class BatExecutor {

    public static void executeBatFile(String batFilePath) {
        try {
            // 使用ProcessBuilder来启动.bat文件
            ProcessBuilder processBuilder = new ProcessBuilder(batFilePath);
            processBuilder.redirectErrorStream(true); // 将错误流和标准输出流合并
            Process process = processBuilder.start();

            // 读取合并后的输出流(包括标准输出和错误输出)
            try (InputStream inputStream = process.getInputStream();
                 BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
                
                String line;
                while ((line = reader.readLine()) != null) {
                    System.out.println(line); // 打印输出,避免阻塞
                }
            }

            // 等待进程结束
            int exitCode = process.waitFor();
            System.out.println("Bat file executed with exit code " + exitCode);

        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        String batFilePath = "path/to/your/batchfile.bat"; // 修改为你的.bat文件路径
        executeBatFile(batFilePath);
    }
}

在这个示例中,我们使用了`ProcessBuilder`来启动`.bat`文件,并通过调用`redirectErrorStream(true)`将错误输出流和标准输出流合并。然后,我们使用`BufferedReader`来读取合并后的输出流,并将其内容打印到控制台。这样做可以避免由于输出流或错误流未被读取而导致的阻塞问题。

请注意,你需要将`batFilePath`变量的值替换为你的`.bat`文件的实际路径。此外,这个示例还演示了如何等待外部进程结束并获取其退出代码。