Java判断文件EOF统计行数时Scanner无限循环原因及优化方案
问题1:无限循环原因
Scanner类的hasNextLine()方法仅会检测当前读取指针后是否存在下一行内容,不会移动读取指针的位置。你注释掉f.nextLine()调用后,读取指针一直停留在文件的初始位置,每次循环调用hasNextLine()都会检测到剩余内容存在,永远返回true,因此会进入无限循环。f.nextLine()的核心作用除了读取当前行内容返回外,还会将读取指针后移到下一行的起始位置,只有指针移动到文件末尾后,hasNextLine()才会返回false,循环才能正常退出。
问题2:无需存储字符串的统计实现
存在多种实现方式,以下是几种常见方案:
方案1:直接调用nextLine()不赋值
沿用你现有代码的逻辑,不需要把nextLine()的返回值赋值给变量即可,不会产生额外的字符串存储开销:
static int findFileSize(Scanner f){ System.out.println("Got to counter:"); int line_count = 0; while(f.hasNextLine()) { line_count++; System.out.println(line_count); f.nextLine(); // 不赋值给变量,仅移动指针 } System.out.println("File size: " + line_count); return line_count; }
方案2:使用LineNumberReader实现(性能更优)
LineNumberReader自带行号统计能力,不需要手动计数:
import java.io.FileReader; import java.io.IOException; import java.io.LineNumberReader; static int findFileSize(FileReader fileReader) throws IOException { try (LineNumberReader lineNumberReader = new LineNumberReader(fileReader)) { // 直接跳到文件末尾 lineNumberReader.skip(Long.MAX_VALUE); // LineNumberReader行号从0开始,所以返回值需要+1 return lineNumberReader.getLineNumber() + 1; } }
方案3:使用Java 8+文件流实现(代码最简洁)
import java.nio.file.Files; import java.nio.file.Path; import java.io.IOException; static long findFileSize(Path filePath) throws IOException { // 流会自动关闭,直接统计行数即可 try (var linesStream = Files.lines(filePath)) { return linesStream.count(); } }
内容的提问来源于stack exchange,提问作者Zileith
相关产品推荐
相关产品推荐

