Java运行while循环抛出NoSuchElementException无法迭代如何修复
问题根因
- 直接触发报错的原因是
createFile方法中关闭了基于System.in构建的BufferedReader,System.in是JVM全局共享的标准输入流,一旦关闭后,外层的Scanner后续再尝试读取输入时,因为输入流已经被销毁,就会抛出NoSuchElementException。 - 除此之外代码还有几处逻辑错误:
- 菜单选择的读取逻辑只在进入循环前执行了一次,执行完任意操作后不会重新展示菜单、读取用户新的选择,会无限重复执行第一次选择的功能
- 文件路径拼接时直接使用了单个未转义的反斜杠,会触发编译错误,也不支持跨平台运行
deleteFile方法内部打印了输入文件名的提示,但没有实际读取用户输入,直接使用了外层传入的参数,功能不符合设计预期
修复后的完整代码
import java.io.*; import java.util.Scanner; public class Main { public static void main(String[] args) throws IOException { showMenu(); } static void showMenu() throws IOException { Scanner scan = new Scanner(System.in); while (true) { // 菜单逻辑移到循环内部,每次操作完重新展示菜单 menuOptions(); int userMenuInput = 0; if (scan.hasNextLine()) { try { userMenuInput = Integer.parseInt(scan.nextLine()); } catch (NumberFormatException e) { System.out.println("请输入有效的数字"); } } switch (userMenuInput) { case 1: System.out.println("请输入要创建的文件名:"); String userFileName = scan.nextLine(); createFile(userFileName + ".txt"); break; case 2: System.out.println("请输入要删除的文件名:"); String userDeleteFile = scan.nextLine(); deleteFile(userDeleteFile); break; case 3: System.out.println("Write to a file"); break; case 4: System.out.println("Exit from program"); scan.close(); // 程序退出前再关闭Scanner System.exit(0); break; default: System.out.println("Please type from 1 to 4!"); } } } private static void createFile(String fileName){ System.out.println(System.getProperty("user.dir")); // 修复路径拼接逻辑,用File.separator保证跨平台兼容 File myFile = new File(System.getProperty("user.dir") + File.separator + fileName); try { myFile.createNewFile(); BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); PrintWriter out = new PrintWriter(new FileWriter(myFile)); String s; System.out.print("Enter text: "); while ((s = in.readLine()) != null && (s.length() != 0)) { out.println(s); } // 移除in.close(),不要关闭全局System.in流 out.close(); // 只关闭文件写入流 } catch (IOException e) { System.out.println("File writing failed!"); } System.out.println(myFile.getAbsolutePath()); } private static void deleteFile(String fileNameToDelete){ try{ File sourceFile = new File(fileNameToDelete+".txt"); if(sourceFile.delete()){ System.out.println("删除成功"); }else{ System.out.println("删除失败,文件不存在或无权限"); } } catch (Exception ex) { System.out.println(ex.getMessage()); } } private static void menuOptions(){ System.out.println("Choose from these choices"); System.out.println("-------------------------\n"); System.out.println("1 - Create file"); System.out.println("2 - Delete file"); System.out.println("3 - Write to file"); System.out.println("4 - Quit"); System.out.println(); } }
核心修改点说明
- 删除了
createFile方法中in.close()的代码,避免全局输入流被提前关闭 - 将菜单展示、用户菜单选择读取的逻辑移到
while(true)循环内部,每次操作完成后都可以重新选择功能 - 修复了文件路径拼接逻辑,使用
File.separator替代硬编码的反斜杠,避免编译错误同时支持跨平台运行 - 优化了删除文件的反馈逻辑,增加了删除成功/失败的提示
- 仅在程序退出前关闭
Scanner,避免提前销毁输入流
内容的提问来源于stack exchange,提问作者Kalman Yudin
相关产品推荐
相关产品推荐

