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

如何实现Txt存储的Top10玩家高分榜并修复写入为空问题

修复高分榜文件为空问题并实现需求

核心问题分析

原代码存在以下关键缺陷导致文件无法正确保存有效高分数据:

  • updateHighScores仅将新分数追加到文件,排序操作仅在内存中完成,未将排序后的最终结果写回文件
  • writeHighScores使用追加模式打开文件,无法覆盖旧数据,导致文件只会无意义累加条目
  • readHighScores预初始化10个空分数条目,会把无效的0分条目混入结果,干扰最终写入逻辑

修复后的完整代码

import java.io.FileWriter;
import java.io.IOException;
import java.util.Scanner;
import java.util.Formatter;
import java.nio.file.Paths;

public class HighScore {

    // 改为静态内部类,消除外部类实例依赖问题
    public static class HighScoreEntry {
        private String name;
        private int score;

        public HighScoreEntry(String name, int score) {
            this.name = name;
            this.score = score;
        }

        public String getName() {
            return name;
        }

        public int getScore() {
            return score;
        }
    }

    // 修改为覆盖写入模式,每次写入完整的有效高分榜
    public void writeHighScores(HighScoreEntry[] highScores) {
        Formatter f = null;
        FileWriter fw = null;
        try {
            // 去掉追加参数,改为覆盖写入
            fw = new FileWriter("highscores.txt");
            f = new Formatter(fw);
            for (HighScoreEntry entry : highScores) {
                // 仅写入有效条目(排除空名称和0分的无效数据)
                if (!entry.getName().isEmpty() && entry.getScore() > 0) {
                    f.format("%s:%d%n", entry.getName(), entry.getScore());
                }
            }
        } catch (IOException e) {
            System.out.println("写入高分文件时发生错误。");
        } finally {
            if (f != null) {
                f.close();
            }
            try {
                if (fw != null) {
                    fw.close();
                }
            } catch (IOException e) {
                System.out.println("关闭文件流时发生错误。");
            }
        }
    }
    
    public HighScoreEntry[] readHighScores() {
        // 临时数组存储所有读取到的有效条目
        HighScoreEntry[] tempEntries = new HighScoreEntry[100];
        int count = 0;
        
        Scanner reader = null;

        try {
            reader = new Scanner(Paths.get("highscores.txt"));
            while (reader.hasNextLine() && count < 100) {
                String line = reader.nextLine();
                String[] parts = line.split(":");
                if (parts.length == 2) { // 校验格式合法性
                    String name = parts[0].trim();
                    int score = Integer.parseInt(parts[1].trim());
                    if (!name.isEmpty() && score > 0) { // 过滤无效条目
                        tempEntries[count] = new HighScoreEntry(name, score);
                        count++;
                    }
                }
            }
        } catch (IOException e) {
            // 首次游戏时文件不存在属于正常情况,无需抛出错误
            System.out.println("读取高分文件时发生错误(首次游戏时此为正常情况)。");
        } finally {
            if (reader != null) {
                reader.close();
            }
        }
        
        // 转换为实际长度的数组,最多保留10条
        int actualLength = Math.min(count, 10);
        HighScoreEntry[] highScores = new HighScoreEntry[actualLength];
        System.arraycopy(tempEntries, 0, highScores, 0, actualLength);
        return highScores;
    }

    public void updateHighScores(String name, int score) {
        System.out.println("更新高分榜:玩家 " + name + " 分数 " + score);
        
        // 1. 读取现有所有有效高分
        HighScoreEntry[] existingScores = readHighScores();
        
        // 2. 合并现有条目与新条目
        HighScoreEntry[] allScores = new HighScoreEntry[existingScores.length + 1];
        System.arraycopy(existingScores, 0, allScores, 0, existingScores.length);
        allScores[existingScores.length] = new HighScoreEntry(name.trim(), score);
        
        // 3. 按分数从高到低排序
        sortHighScores(allScores);
        
        // 4. 截取前10条有效数据
        int finalLength = Math.min(allScores.length, 10);
        HighScoreEntry[] finalScores = new HighScoreEntry[finalLength];
        System.arraycopy(allScores, 0, finalScores, 0, finalLength);
        
        // 5. 将最终结果覆盖写入文件
        writeHighScores(finalScores);
    }    

    private void sortHighScores(HighScoreEntry[] highScores) {
        for (int i = 0; i < highScores.length - 1; i++) {
            for (int j = i + 1; j < highScores.length; j++) {
                // 处理空条目,统一放到最后
                if (highScores[i] == null) {
                    HighScoreEntry temp = highScores[i];
                    highScores[i] = highScores[j];
                    highScores[j] = temp;
                } else if (highScores[j] != null && highScores[i].getScore() < highScores[j].getScore()) {
                    HighScoreEntry temp = highScores[i];
                    highScores[i] = highScores[j];
                    highScores[j] = temp;
                }
            }
        }
    }
}

关键修改说明

  • 重构更新逻辑:改为"读取-合并-排序-截取-写入"的完整流程,确保文件始终保存最新的排序结果
  • 切换写入模式:FileWriter去掉追加参数,使用覆盖写入,避免旧数据残留
  • 优化读取逻辑:不再预生成空条目,仅收集有效分数,过滤无效数据
  • 内部类静态化:消除内部类对外部类实例的依赖,避免潜在初始化问题
  • 增加数据校验:读取和写入时过滤空名称、0分等无效条目,保证数据有效性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 09:25:41