Java开发高分榜时读取文件存入ArrayList无法识别已有内容问题
核心问题根因
你现在遇到的“明明文件有有效内容,程序却读不到任何数据”是由完全颠倒的IO操作顺序导致的,具体触发逻辑如下:
- Java 中不带追加参数的
new FileWriter(文件路径),在实例化完成的瞬间,就会直接把目标文件截断为0长度的空文件,不会等你后续调用写方法才清空内容。 - 你在方法最开头,还没开始用Scanner读取文件历史内容时,就已经初始化了指向两个高分文件的
FileWriter实例。这两个初始化操作一执行,你磁盘上本来存着历史高分数据的highscorenames.txt、highscores.txt就已经被清空成了空文件。 - 等你后续再初始化Scanner、循环读文件内容时,读到的自然是清空后的空文件,两个ArrayList的size永远为0,完全读不到之前存的有效数据。
其他存在的代码缺陷
- 流程逻辑错位:本来应该是「读历史内容→加载到内存列表→完成新用户分数的榜单插入排序→回写更新后的内容到文件」,你现在把写流的初始化放在了读操作之前,直接打断了整个流程的正常执行。
- IO资源未正确释放:所有打开的读流(Scanner包装的FileReader)、写流(PrintWriter包装的FileWriter)都没有在使用完成后调用close方法,不仅会造成系统资源泄漏,还可能因为写缓冲区没有强制刷新,导致写入文件的内容丢失。
- 冗余的清空操作:你代码里写的
printWriter1.print("")、printWriter2.print("")本来是为了清空旧文件内容,实际上因为FileWriter初始化时已经完成了文件截断,这两行代码没有任何实际作用,反而因为顺序错位加剧了读不到内容的问题。 - 榜单逻辑漏洞:当前实现没有控制高分榜的最大条目数,一旦用户达到入榜分数就直接插入列表,长期运行会导致存储的条目无限增长,失去高分榜的功能意义。
核心修正逻辑
只需要调整IO操作的先后顺序,就能解决读不到内容的问题:
- 先完成两个高分文件的读取操作,把所有历史内容加载到两个ArrayList中,读完立刻关闭读流
- 执行完新用户分数的对比、插入排序逻辑
- 所有内存中的榜单数据处理完成后,再初始化FileWriter/PrintWriter写流,把更新后的榜单内容回写到文件,写完关闭写流
修正后的核心顺序代码参考:
public static void HighScore() throws IOException { ArrayList<String> nameList = new ArrayList<>(); ArrayList<Integer> scoreList = new ArrayList<>(); int temp1; String temp2; int userScore = 100; String userName = "Richard"; // 第一步:先读历史内容,此时不打开任何写流 File nameFile = new File("highscorenames.txt"); File scoreFile = new File("highscores.txt"); // 提前判断文件是否存在,避免不存在时抛异常 if (nameFile.exists() && scoreFile.exists()) { Scanner names = new Scanner(new FileReader(nameFile)); Scanner scores = new Scanner(new FileReader(scoreFile)); while (names.hasNextLine()) { nameList.add(names.nextLine()); } while (scores.hasNextLine()) { scoreList.add(Integer.parseInt(scores.nextLine())); } // 读完立刻关闭读流 names.close(); scores.close(); } System.out.println("读到的历史榜单条目数:" + scoreList.size()); System.out.println(nameList.size()); // 第二步:执行分数对比、插入排序逻辑(和原代码一致) for(int i = 0; i < scoreList.size(); i++) { if(userScore > scoreList.get(i)) { temp1 = scoreList.get(i); scoreList.set(i,userScore); userScore = temp1; temp2 = nameList.get(i); nameList.set(i,userName); userName = temp2; } } // 第三步:所有内存数据处理完成后,再打开写流回写文件 FileWriter nameWriter = new FileWriter("highscorenames.txt"); FileWriter scoreWriter = new FileWriter("highscores.txt"); PrintWriter printWriter1 = new PrintWriter(nameWriter); PrintWriter printWriter2 = new PrintWriter(scoreWriter); for(int j = 0; j < nameList.size(); j++) { printWriter1.println(nameList.get(j)); } for(int k = 0; k < scoreList.size(); k++) { printWriter2.println(scoreList.get(k)); } // 写完关闭写流,刷新缓冲区 printWriter1.close(); printWriter2.close(); }
内容的提问来源于stack exchange,提问作者ulhaon
相关产品推荐
相关产品推荐

