用纯文本每行存一条记录(如playerName,2450,2024-05-12 14:22),追加写入需new FileWriter("scores.txt", true),读取后split解析并try-catch处理异常,排序后截取前10名覆写文件。

怎么用 Java 把贪吃蛇分数存到文件里
直接用 FileWriter 写文本最简单,但得自己处理换行和字段分隔;更稳妥的是用 ObjectOutputStream 序列化对象,不过要求类实现 Serializable,且后续改类结构容易反序列化失败。日常小项目推荐纯文本 + 每行一条记录,比如:playerName,2450,2024-05-12 14:22。
常见错误现象:FileNotFoundException —— 路径写错或目录不存在;SecurityException(Android 或沙箱环境)—— 控制台程序一般不触发,但 IDE 运行时若工作目录不是项目根,data/scores.txt 会找错地方。
- 用
new File("scores.txt").getAbsolutePath()打印路径,确认文件真正在哪被创建 - 写入前先
file.getParentFile().mkdirs(),避免因父目录不存在而失败 - 别用
PrintWriter.println()直接写对象,它调的是toString(),不是你想要的结构化数据
读取后怎么按分数倒序排又不崩
读出来是字符串行,得先拆分成对象再排序。别在 Comparator 里直接 Integer.parseInt() 然后忽略异常——一旦某行格式错(比如空行、缺字段),整个排序就抛 NumberFormatException 崩掉。
使用场景:启动游戏时加载历史榜,或结算后刷新显示。排序本身开销极小,瓶颈永远在 IO,所以别想着“先读再筛再排”,一步到位更稳。
立即学习“Java免费学习笔记(深入)”;
- 每行用
String.split(",")拆,长度不等于 3 就跳过 - 分数字段用
try-catch包住Integer.parseInt(),解析失败则设为 0 或丢弃 - 排序写成:
list.sort((a, b) -> Integer.compare(b.score, a.score)),注意是b - a实现倒序
为什么每次运行排行榜都清空了
因为用了 new FileWriter("scores.txt") 而没传 true 参数,默认覆盖写。想追加得分,必须显式开启 append 模式。
性能影响几乎为零,但兼容性要注意:Windows 下换行符是 \r\n,Linux/macOS 是 \n,用 System.lineSeparator() 更安全;另外多线程写同一文件会乱,控制台单线程不用管。
- 追加写:用
new FileWriter("scores.txt", true) - 但别在每次
addScore()都打开/关闭文件——频繁 IO 慢,建议攒几条再刷盘,或用BufferedWriter提升效率 - 如果用
Files.write(),它默认覆盖,要追加得加StandardOpenOption.APPEND
排行榜最多只显示前 10 名,怎么删老数据
不是“写满 10 条就停”,而是每次保存新成绩后,重载全部、排序、截取前 10、再全量覆写文件。否则靠“删最后一行”这种逻辑,在多人同名、分数相同时极易出错。
容易踩的坑:用 List.subList(0, Math.min(10, list.size())) 后直接写回文件——这没问题;但如果之前用 TreeSet 去重,可能误删同分不同人;或者用 LinkedHashSet 保留顺序但没排序,就白做了。
- 务必在截取前完成完整排序(含同分时按时间或名字次序)
- 覆写文件前,先用
Files.deleteIfExists(path)确保旧文件不残留锁或权限问题 - 如果担心写一半崩溃导致榜单丢失,可先写到
scores.tmp,成功后再原子替换原文件(Files.move(tmp, real, REPLACE_EXISTING))
真正麻烦的从来不是排序或 IO,而是“用户改了名字、删了文件、手动编辑内容格式错乱”——这些没法靠代码兜底,只能靠健壮的解析逻辑扛住脏数据。










