Java文件流“java.io.IOException: Stream closed”异常解决

2022-06-23 08:45:41

Java文件流“java.io.IOException: Stream closed”异常解决

初学者在Java的io流操作中往往最容易忘记的就是处理完之后流的关闭,但是好不容易记起来了,却又出现java.io.IOException: Stream closed的异常,现在以记事本案例来演示此问题。

该异常提示“流”已经关闭,但是我们观察源代码,发现我们打开了两个流,之后关闭这两个流,但为什么提示流已经关闭呢?

要想解决这一个问题,首先需要了解“修饰类”的概念,在这里“FileWriter   是被修饰者,BufferedWriter   是修饰者”,也可以通过增加File类缓冲提高学性能。
既然知道“FileWrite”是被修饰者,“BufferedWrite”是修饰者,如果用“嵌套”这个概念来理解这一问题,那么很明显,“FileWrite”是嵌套在“BufferedWrite”中的,所以,当先关闭“FileWrite”流时,“BufferedWrite”自然没有了修饰对象,所以会抛出异常。
解决方法就是先关闭“BufferedWrite”修饰流,再关闭“FillWrite”流即可,如下图:

问题成功解决!

另外多说一句,“FileReader”和“BufferedReader”没有此问题。

在最后附上源代码,仅供参考:
/*
 * 引包
 */
import java.awt.*;
import javax.swing.*;
import java.io.*;
import java.awt.event.*;

/**
 * 记事本界面设计
 * @author guoqiang
 *
 */
public class Window extends JFrame implements ActionListener {
	/* 定义组件 */
	JTextArea mainJTA = null;			// 主界面的文本输入
	JMenuBar jmenubar = null;			// 菜单条
	JMenu jmenu = null;					// 一级菜单
	JMenuItem jmenuitemOpen = null;		// 菜单选项
	JMenuItem jmenuitemSave = null;		// 保存
	
	/**
	 * 构造函数,实现组建的初始化
	 */
	public Window() {
		/* 创建对象 */
		mainJTA = new JTextArea();
		jmenubar = new JMenuBar();
		jmenu = new JMenu("文件 (Alt+F)");
		jmenuitemOpen = new JMenuItem("打开");
		jmenuitemSave = new JMenuItem("保存");
		
		/* 设置助记符 */
		jmenu.setMnemonic('F');
		
		/* 设置页面布局 */
		this.setLayout(new BorderLayout());
		
		/* 添加组件 */
		this.add(mainJTA);
		
		/* 注册监听 */
		jmenuitemOpen.addActionListener(this);
		jmenuitemOpen.setActionCommand("open");
		jmenuitemSave.addActionListener(this);
		jmenuitemSave.setActionCommand("save");
		
		// 添加菜单条
		this.setJMenuBar(jmenubar);
		jmenubar.add(jmenu);
		jmenu.add(jmenuitemOpen);
		jmenu.add(jmenuitemSave);
		
		/* 设置窗体属性 */
		this.setSize(500, 350);
		this.setLocation(300, 200);
		this.setTitle("记事本");
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setIconImage(new ImageIcon("images/star.gif").getImage());
		
		/* 显示窗体 */
		this.setVisible(true);
	}

	/**
	 * 重写ActionListener的方法
	 */
	@Override
	public void actionPerformed(ActionEvent e) {
		// 判断哪个菜单被选中
		if (e.getActionCommand().equals("open")) {
			// 创建文件选择对象
			JFileChooser jfilechooser = new JFileChooser();
			jfilechooser.setDialogTitle("请选择文件...");			// 选择文件的对话框的标题
			jfilechooser.showOpenDialog(null);					// 按照默认属性弹出对话框, null表示默认属性
			jfilechooser.setVisible(true);						// 窗体可见
			
			// 得到用户选择的文件路径
			String fileName = jfilechooser.getSelectedFile().getAbsolutePath();		// 得到绝对路径
			
			/* 文件流 */
			FileReader filereader = null;
			BufferedReader bufferedreader = null;
			
			/* 异常处理 */
			try {
				/* 文件字符流 */
				String s = null;
				String allChar = null;
				
				filereader = new FileReader(fileName);		// 德大哦文件路径
				bufferedreader = new BufferedReader(filereader);
				
				while ((s = bufferedreader.readLine()) != null) {
					allChar += s + "\r\n";		// 字符串拼接
				}
				
				/* 在JTextArea中显示 */
				mainJTA.setText(allChar);		// 该方法继承于javax.swing.text.JTextComponent
			} catch (Exception e1) {
				e1.printStackTrace();
			} finally {
				// 关闭文件流
				try {
					bufferedreader.close();
					filereader.close();
				} catch (IOException e1) {
					e1.printStackTrace();
				}
			}
		} else if (jmenuitemSave.getActionCommand().equals("save")) {		// 选择保存菜单
			// 另存为对话框
			JFileChooser jfilechooser = new JFileChooser();
			jfilechooser.setDialogTitle("另存为...");
			jfilechooser.showSaveDialog(null);					// 按照默认属性弹出对话框, null表示默认属性
			jfilechooser.setVisible(true);
			
			/* 得到保存的路径 */
			String savePath = jfilechooser.getSelectedFile().getAbsolutePath();	// 得到绝对路径

			/* 此处应该判断是否真的选择了地址,如果只是打开却没有选择,会抛出 java.lang.NullPointerException*/
			
			/* 写入到指定文件 */
			FileWriter filewrite = null;
			BufferedWriter bufferedwrite = null;
			try {
				filewrite = new FileWriter(savePath);
				bufferedwrite = new BufferedWriter(filewrite);
				
				// 将JTextArea中的内容写入到指定文件
				bufferedwrite.write(this.mainJTA.getText());

			} catch (Exception e2) {
				e2.printStackTrace();
			} finally {
				try {
					/* 关闭文件流 */
					bufferedwrite.close();
					filewrite.close();
					
				} catch (Exception e3) {
					// TODO: handle exception
					e3.printStackTrace();
				}
			}
		}
		
	}
}
  • 作者:3823丶
  • 原文链接:https://blog.csdn.net/CN_3823/article/details/78610184
    更新时间:2022-06-23 08:45:41