Java输入double类型时触发IOException:流已关闭问题咨询
java.io.IOException: Stream closed 异常问题 看起来你遇到的这个异常,核心原因是程序中某个输入/输出流已经被关闭,但后续代码又尝试使用这个已关闭的流。从你的栈跟踪信息来看,问题出在addMenu方法的第181行调用flush()时,发现关联的流已经被关闭了。下面给你具体的排查和修复方案:
常见原因与修复步骤
检查是否提前关闭了系统标准流
很多开发者会不小心关闭System.in、System.out这类系统标准流,或者关闭了包装这些流的对象(比如Scanner、OutputStreamWriter)。这些流由JVM自动管理,除非你明确知道自己的操作逻辑,否则绝对不要手动关闭它们。比如如果在AdminLogin或adminMenu方法里调用了scanner.close()或者writer.close(),会直接导致后续流操作失败。定位流关闭的具体位置
看栈跟踪里的main.java:181,也就是addMenu方法中触发异常的那一行,检查对应的流对象是在哪里被创建和关闭的。比如如果是用OutputStreamWriter包装了System.out,要确认是不是在之前的代码中已经调用了它的close()方法——一旦关闭,后续的flush()就会抛出Stream closed异常。避免重复创建并关闭流对象
如果你的代码在多个方法中重复创建流对象(比如每次调用方法都新建一个Scanner或OutputStreamWriter),并且每次都关闭,很容易导致流被提前关闭。建议复用同一个流实例,或者只在整个程序的最后阶段统一关闭(针对非系统流)。
错误示例与修复
错误场景1:提前关闭System.out的包装流
public void AdminLogin() { OutputStreamWriter writer = new OutputStreamWriter(System.out); writer.write("管理员登录成功"); writer.close(); // 错误:这里关闭了流,后续addMenu无法再使用 adminMenu(); } public void addMenu() { OutputStreamWriter writer = new OutputStreamWriter(System.out); writer.write("请输入要添加的菜单编号:"); writer.flush(); // 此处抛出Stream closed异常 }
修复后代码
public void AdminLogin() { OutputStreamWriter writer = new OutputStreamWriter(System.out); writer.write("管理员登录成功"); writer.flush(); // 只刷新内容,不关闭流 adminMenu(); } public void addMenu() { OutputStreamWriter writer = new OutputStreamWriter(System.out); writer.write("请输入要添加的菜单编号:"); writer.flush(); // 系统标准流无需手动关闭,JVM会自动处理 }
错误场景2:关闭Scanner导致System.in被关闭
public void AdminLogin() { Scanner scanner = new Scanner(System.in); System.out.print("请输入密码:"); String pwd = scanner.nextLine(); scanner.close(); // 错误:关闭Scanner会同时关闭System.in adminMenu(); } public void addMenu() { Scanner scanner = new Scanner(System.in); // 此处因为System.in已关闭,会触发异常 int menuId = scanner.nextInt(); }
修复后代码
// 把Scanner作为类成员变量复用,避免多次创建和关闭 private static Scanner scanner = new Scanner(System.in); public void AdminLogin() { System.out.print("请输入密码:"); String pwd = scanner.nextLine(); adminMenu(); } public void addMenu() { System.out.print("请输入要添加的菜单编号:"); int menuId = scanner.nextInt(); } // 程序结束前再关闭(可选,JVM也会自动处理) public static void main(String[] args) { // ... 业务逻辑 ... scanner.close(); }
总结
这个异常的核心就是流的生命周期管理问题——确保所有需要使用的流,在其所有操作完成前都处于开放状态,尤其是系统标准流(System.in/System.out)不要随意关闭。按照上面的步骤排查你的代码,应该很快能解决问题。
内容的提问来源于stack exchange,提问作者Kevin Julianto

