You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过ProcessBuilder使用BufferedReader和BufferedWriter与进程控制台交互?

文本版BlackJack机器人写入操作无响应问题排查与修复

我开发了一款文本版BlackJack游戏,正在编写机器人程序自动游玩并记录结果。目前已成功启动游戏进程并读取控制台初始数据,但机器人确定操作后,既无法将操作写入游戏控制台,也无法获取游戏返回的响应。

当前代码如下:

public static void main(String[] args) {
        try {
            ProcessBuilder builder = new ProcessBuilder("java","app.App");
            builder.directory(new File("C:\\Users\\damon\\OneDrive\\school\\code\\BlackJack"));
            builder.redirectErrorStream(true);
            Process process = builder.start();

            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(process.getOutputStream()));
                    String line1 = reader.readLine(); // Player's total
                    String line2 = reader.readLine(); // Player's cards
                    String line3 = reader.readLine(); // Can split
                    String line4 = reader.readLine(); // Dealer's total
                    String line5 = reader.readLine(); // Dealer's cards
                    // Process the lines to extract and store the data
                    int playersTotal = Integer.parseInt(line1);
                    String[] playerCards = line2.split(" ");
                    boolean canSplit = line3.equals("s");
                    int dealersTotal = Integer.parseInt(line4);
                    String[] dealerCards = line5.split(" ");
                    Stratergy strat=new Stratergy(playersTotal, playerCards[0], canSplit,dealersTotal);
                    writer.write(strat.suggestAction()+"\n");
                    System.out.println(line1+"\n"+line2+"\n"+line3+"\n"+line4+"\n"+line5+"\n"+strat.suggestAction());
                    System.out.println(reader.readLine());          
            reader.close();

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

问题根源分析

  1. 缓冲输出未刷新:BufferedWriter的write()方法会把数据暂存在缓冲区,没有直接发送给子进程,游戏根本没收到操作指令。
  2. 资源关闭时机错误:读取响应前就关闭了reader,导致后续读取操作直接失败。
  3. 未处理交互阻塞:如果游戏有持续输出,主线程可能因等待输入而卡住,影响交互流程。

修复后的代码

public static void main(String[] args) {
    Process process = null;
    BufferedReader reader = null;
    BufferedWriter writer = null;
    try {
        ProcessBuilder builder = new ProcessBuilder("java", "app.App");
        builder.directory(new File("C:\\Users\\damon\\OneDrive\\school\\code\\BlackJack"));
        builder.redirectErrorStream(true);
        process = builder.start();

        reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
        writer = new BufferedWriter(new OutputStreamWriter(process.getOutputStream()));

        // 读取初始游戏数据
        String line1 = reader.readLine();
        String line2 = reader.readLine();
        String line3 = reader.readLine();
        String line4 = reader.readLine();
        String line5 = reader.readLine();

        // 解析数据
        int playersTotal = Integer.parseInt(line1);
        String[] playerCards = line2.split(" ");
        boolean canSplit = line3.equals("s");
        int dealersTotal = Integer.parseInt(line4);

        // 获取策略操作
        Stratergy strat = new Stratergy(playersTotal, playerCards[0], canSplit, dealersTotal);
        String action = strat.suggestAction();
        
        // 写入操作并强制刷新缓冲区,确保游戏收到指令
        writer.write(action + "\n");
        writer.flush();

        // 调试输出
        System.out.println(line1 + "\n" + line2 + "\n" + line3 + "\n" + line4 + "\n" + line5 + "\n" + action);
        
        // 读取游戏响应
        String response = reader.readLine();
        if (response != null) {
            System.out.println("游戏返回:" + response);
        } else {
            System.out.println("未收到响应,游戏进程可能已终止");
        }

    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        // 按顺序关闭资源,避免泄漏
        try {
            if (writer != null) writer.close();
            if (reader != null) reader.close();
            if (process != null) process.destroy();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

额外优化建议

  • 分离输入输出线程:如果游戏是多轮交互,单独开线程处理读取输出,避免主线程因等待输入阻塞,比如用一个线程循环读取游戏输出并打印,主线程专注发送操作指令。
  • 适配换行符:Windows环境下部分程序需要\r\n作为换行符,可尝试替换writer.write(action + "\n")为writer.write(action + "\r\n")。
  • 检查进程状态:用process.isAlive()判断游戏进程是否存活,排查是否进程意外退出导致无响应。

内容的提问来源于stack exchange,提问作者Damon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 08:00:59