如何实现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
相关产品推荐
相关产品推荐

