Java文件读取程序中Scanner调用nextLine报NoSuchElementException
异常触发的根本原因
java.util.Scanner 存在一个极易被新手忽略的底层逻辑:当 Scanner 绑定的输入源是全局标准输入流 System.in 时,调用 Scanner 实例的 close() 方法,并不会仅关闭 Scanner 本身,而是会直接关闭底层共享的 System.in 输入通道。
- 你在读完用户输入的文件路径后,立刻对第一个绑定
System.in的Scanner实例scanTwo执行了scanTwo.close(),这一步直接把全局控制台的输入通道永久关闭了。 - 后续你新建第二个Scanner实例
scan尝试绑定System.in读取命令时,拿到的已经是被关闭、没有任何可用输入数据的失效通道,调用scan.nextLine()时检测不到可读取的内容,直接抛出NoSuchElementException: No line found。
代码中存在的其他连带逻辑问题
- 读取本地文件的
fileScanner,在打印完文件第一行后就被提前调用close()关闭了。后续if分支里无论是执行打印全文的逻辑,还是统计单词数的逻辑,再去操作已经关闭的文件Scanner,会直接触发非法状态异常,即使解决了控制台输入的报错也无法跑通功能。
修正方案
- 全程序仅创建一个绑定
System.in的Scanner实例,全程复用这个实例完成所有控制台输入操作:读取文件路径、读取用户输入的命令,不要中途对这个实例调用close(),等所有控制台输入流程走完后再统一处理资源释放即可。 - 不要在读取文件的中途关闭对应文件的Scanner,等文件相关的所有操作(全文打印、单词统计)全部完成后,再统一关闭文件流对应的Scanner,避免资源提前失效。
举个最小修改示例:把原来代码里的
scanTwo、后续新建的scan合并成同一个实例,删除scanTwo.close()的调用、删除后续提前关闭fileScanner的那行代码,程序即可正常运行。
内容的提问来源于stack exchange,提问作者Omar Faris
相关产品推荐
相关产品推荐

