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

PrintWriter异常求助:国际象棋游戏存档功能无法正常工作

排查APCS国际象棋存档类SaveListener的输出异常问题

我在为APCS期末项目编写国际象棋游戏的存档类SaveListener时碰到了个头疼的问题:这个类本该完整保存整个棋局的状态,但实际运行后,生成的文件里居然只有ro00\n这一行内容。我试过更换Writer类型、添加/移除flush()操作等多种写法,当前版本已经是最接近正常的了,附上相关代码和期望结果,麻烦帮忙排查下问题!

问题代码片段

class SaveListener implements ActionListener {
    String temp;
    public void actionPerformed(ActionEvent e) {
        System.out.println(">saveInitiated");
        try {
            write = new PrintWriter(new OutputStreamWriter(
                    new FileOutputStream("Board.txt"), "utf-8"));
            /*write = new PrintWriter(new File("Board.txt"), "UTF-8");*/
            for (int y = 0; y < 8; y ++) {
                for (int x = 0; x < 8; x++) {
                    System.out.printf(">>y:%d,x:%d\n", y, x);
                    if (Board[y][x] != null) {
                        temp = Board[y][x].getType();
                        switch (temp) {
                            case "pawn": write.print("pa"); break;
                            case "rook": write.print("ro"); break;
                            case "knight": write.print("kn"); break;
                            case "bishop": write.print("bi"); break;
                            case "queen": write.print("qu"); break;
                            case "king": write.print("ki"); break;
                        }
                        write.flush();
                        write.print(y);
                        write.flush();
                        write.print(x + "\n");
                        write.flush();
                    } else {
                        write.print("nu\n");
                    }
                    write.close(); // 这里就是问题根源!
                }
            }
        } catch (FileNotFoundException e1) {
            System.out.println(">>FileNotFound!");
        } catch (UnsupportedEncodingException e1) {
            System.out.println(">>unsupportedEncodingException");
        }
        System.out.println(">saveConcluded");
    }
}

正常参考代码(可正常完整存档)

if (save) {
    PrintWriter write = new PrintWriter("Board.txt", "UTF-8");
    for (int y = 0; y < board.length; y++) {
        for (int x = 0; x < board[y].length; x++) {
            write.print(board[y][x] + " ");
        }
    }
    write.close(); // 所有写入完成后才关闭流
    System.out.println("Saved");
    save = false;
}

期望生成的文件内容

(空格仅为可读性添加,实际无空格)
ro00\n kn01\n bi02\n ki03\n qu04\n bi05\n kn06\n ro07\n pa00\n pa01\n pa02\n pa03\n pa04\n pa05\n pa06\n pa07\n nu\n nu\n ...(中间空行省略)... pa60\n pa61\n ... ro77


问题根源分析

你代码里最致命的错误是在最内层的x循环里就调用了write.close()!这意味着第一次循环(y=0,x=0)执行完之后,输出流就被直接关闭了,后面所有的写入操作都会因为流已关闭而失效,所以最终文件里只会保留第一个棋子的记录ro00\n。

另外还有个小细节:你每次写入后都调用flush()其实没必要,PrintWriter本身带有缓冲机制,在关闭流的时候会自动把缓冲区的内容写入文件,频繁调用flush()反而会降低性能。

修复后的代码

class SaveListener implements ActionListener {
    public void actionPerformed(ActionEvent e) {
        System.out.println(">saveInitiated");
        PrintWriter write = null; // 提前声明变量
        try {
            write = new PrintWriter(new OutputStreamWriter(
                    new FileOutputStream("Board.txt"), "utf-8"));
            for (int y = 0; y < 8; y ++) {
                for (int x = 0; x < 8; x++) {
                    System.out.printf(">>y:%d,x:%d\n", y, x);
                    if (Board[y][x] != null) {
                        String temp = Board[y][x].getType(); // 缩小变量作用域
                        switch (temp) {
                            case "pawn": write.print("pa"); break;
                            case "rook": write.print("ro"); break;
                            case "knight": write.print("kn"); break;
                            case "bishop": write.print("bi"); break;
                            case "queen": write.print("qu"); break;
                            case "king": write.print("ki"); break;
                        }
                        write.print(y);
                        write.print(x + "\n");
                    } else {
                        write.print("nu\n");
                    }
                }
            }
            // 所有写入操作完成后再关闭流,自动flush缓冲区
            if (write != null) {
                write.close();
            }
        } catch (FileNotFoundException e1) {
            System.out.println(">>FileNotFound!");
        } catch (UnsupportedEncodingException e1) {
            System.out.println(">>unsupportedEncodingException");
        } finally {
            // 额外保险:确保流被关闭
            if (write != null && !write.checkError()) {
                write.close();
            }
        }
        System.out.println(">saveConcluded");
    }
}

验证建议

运行修改后的代码后,你可以:

  1. 查看控制台的>>y:x日志,确认它打印了所有64个格子的坐标(0-7的y和x组合)
  2. 打开生成的Board.txt文件,检查内容是否和你期望的完整棋局记录一致

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 10:09:02