BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / java / #39976同步于 2015/4/14
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Java机器人发帖

io流文件关闭问题

yzm2010001
2015/4/14镜像同步12 回复
/** * 功能:记事本(界面+功能) */ package com.test6; import java.io.*; import javax.swing.*; import java.awt.*; import java.awt.event.*; public class NotePad extends JFrame implements ActionListener{ //定义需要的组件 JTextArea jta=null; //菜单条 JMenuBar jmb=null; //第一JMenu JMenu jm1=null; //定义一个JMenuItem JMenuItem jmi1=null; JMenuItem jmi2=null; public static void main(String[] args) { // TODO Auto-generated method stub NotePad np=new NotePad(); } //构造函数 public NotePad() { //创建组件 jta=new JTextArea(); jmb=new JMenuBar(); jm1=new JMenu("文件"); //设置助记符 jm1.setMnemonic('F'); jmi1=new JMenuItem("打开"); //注册监听 jmi1.addActionListener(this); jmi1.setActionCommand("open"); jmi2=new JMenuItem("保存"); //对保存菜单处理 jmi2.addActionListener(this); jmi2.setActionCommand("save"); this.setJMenuBar(jmb); jmb.add(jm1); jm1.add(jmi1); jm1.add(jmi2); //放入到JFrame this.add(jta); this.setSize(400,300); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setTitle("NotePad"); this.setVisible(true); } // @Override public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub if(e.getActionCommand().equals("open")) { //System.out.println("open"); //创建一个文件选择组件 JFileChooser jfc1=new JFileChooser(); //设置名字 jfc1.setDialogTitle("请选择文件......"); //默认方式 jfc1.showOpenDialog(null); jfc1.setVisible(true); //得到用户选择文件的全路径 String filename=jfc1.getSelectedFile().getAbsolutePath(); //System.out.println(filename); FileReader fr=null; BufferedReader br=null; try { fr=new FileReader(filename); br=new BufferedReader(fr); String s=""; String allCon=""; while((s=br.readLine())!=null) { allCon+=s+"\r\n"; } //放置到jta即可 jta.setText(allCon); } catch (Exception e2) { e2.printStackTrace(); // TODO: handle exception }finally { try { fr.close(); br.close(); } catch (Exception e3) { // TODO: handle exception e3.printStackTrace(); } } } else if(e.getActionCommand().equals("save")) { //出现保存对话框 JFileChooser jfc=new JFileChooser(); jfc.setDialogTitle("另存为"); //按默认的方式显示 jfc.showSaveDialog(null); jfc.setVisible(true); //得到用户希望把文件保存到何处的全路径 String savename=jfc.getSelectedFile().getAbsolutePath(); //准备写入到指定文件 FileWriter fw=null; BufferedWriter bw=null; try { fw=new FileWriter(savename); bw=new BufferedWriter(fw); bw.write(this.jta.getText()); } catch (Exception e2) { // TODO: handle exception }finally { try { bw.close(); fw.close(); } catch (Exception e3) { // TODO: handle exception e3.printStackTrace(); } } } } } 代码如上,求问为什么最后的finally里的的bw.close()和fw.close()交换一下顺序便会出现一大堆异常,这两个close不是finally才执行的吗?为何会出流关闭错误(以后还要用到?)
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
nuanyangyang机器人#1 · 2015/4/14
哪里有红色? p.s. 要不要试试Java1.7的try-with-resource语句: try (FileWriter fw = new FileWriter(savename); BufferedWriter bw = new BufferedWriter(fw)) { //blah blah blah //blah blah blah //blah blah blah //blah blah blah } // 到这里自动先关闭bw,后关闭fw(相当于finally里按与定义相反的顺序close)
yzm2010001机器人#2 · 2015/4/14
我改了下,设置语法后不能再设置颜色......,只是想知道那个bw和fw不都是finally了吗,前面的流都执行完了,先关哪个有影响?为何先关fw会流关闭异常?莫非bw还要接收fw为参数,此时fw已被关闭,bw找不到fw,是不是这样? 【 在 nuanyangyang 的大作中提到: 】 : 哪里有红色? : p.s. 要不要试试Java1.7的try-with-resource语句: : [code=java] : ...................
yzm2010001机器人#3 · 2015/4/14
强!多谢 【 在 nuanyangyang 的大作中提到: 】 : 哪里有红色? : p.s. 要不要试试Java1.7的try-with-resource语句: : [code=java] : ...................
nuanyangyang机器人#4 · 2015/4/14
【 在 yzm2010001 的大作中提到: 】 : 我改了下,设置语法后不能再设置颜色......,只是想知道那个bw和fw不都是finally了吗,前面的流都执行完了,先关哪个有影响?为何先关fw会流关闭异常?莫非bw还要接收fw为参数,此时fw已被关闭,bw找不到fw,是不是这样? 不管是BufferedWriter还是FileWriter,close方法做的是: Closes the stream, flushing it first. Once the stream has been closed, further write() or flush() invocations will cause an IOException to be thrown. Closing a previously closed stream has no effect. 所以,如果先关FileWriter,那么再关闭bufferedWriter的时候,就会试图flush那个嵌套的FileWriter,就是因为这时候FileWriter已经关闭了,所以flush会出错。 你看看出错的时候,打印出来的stack trace里面是否有FileWriter.flush()这个方法。如果有,就证实了BufferedWriter.close()去间接地调用FileWriter.flush()了。
yzm2010001机器人#5 · 2015/4/14
十分感谢,这是保存文件的时候出的异常(打开文件正常)(fw.close()在前,bw.close()在后) java.io.IOException: Stream closed at sun.nio.cs.StreamEncoder.ensureOpen(StreamEncoder.java:26) at sun.nio.cs.StreamEncoder.write(StreamEncoder.java:99) at java.io.OutputStreamWriter.write(OutputStreamWriter.java:190) at java.io.BufferedWriter.flushBuffer(BufferedWriter.java:111) at java.io.BufferedWriter.close(BufferedWriter.java:246) at com.test6.NotePad.actionPerformed(NotePad.java:159) at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995) at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318) at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387) at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242) at javax.swing.AbstractButton.doClick(AbstractButton.java:357) at javax.swing.plaf.basic.BasicMenuItemUI.doClick(BasicMenuItemUI.java:1225) at javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(BasicMenuItemUI.java:1266) at java.awt.Component.processMouseEvent(Component.java:6216) at javax.swing.JComponent.processMouseEvent(JComponent.java:3265) at java.awt.Component.processEvent(Component.java:5981) at java.awt.Container.processEvent(Container.java:2041) at java.awt.Component.dispatchEventImpl(Component.java:4583) at java.awt.Container.dispatchEventImpl(Container.java:2099) at java.awt.Component.dispatchEvent(Component.java:4413) at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4556) at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4220) at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4150) at java.awt.Container.dispatchEventImpl(Container.java:2085) at java.awt.Window.dispatchEventImpl(Window.java:2475) at java.awt.Component.dispatchEvent(Component.java:4413) at java.awt.EventQueue.dispatchEvent(EventQueue.java:599) at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269) at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184) at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161) at java.awt.EventDispatchThread.run(EventDispatchThread.java:122) 【 在 nuanyangyang 的大作中提到: 】 : : 不管是BufferedWriter还是FileWriter,close方法做的是: Closes the stream, flushing it first. Once the stream has been closed, further write() or flush() invocations will cause an IOException to be thrown. Closing a previously closed stream has no effect. : 所以,如果先关FileWriter,那么再关闭bufferedWriter的时候,就会试图flush那个嵌套的FileWriter,就是因为这时候FileWriter已经关闭了,所以flush会出错。 : ...................
yzm2010001机器人#6 · 2015/4/14
如果这样的话那么第一个finally里的br.close()和fr.close()交换次序为何没有任何影响?(已测试过,无任何影响) 【 在 nuanyangyang 的大作中提到: 】 : : 不管是BufferedWriter还是FileWriter,close方法做的是: Closes the stream, flushing it first. Once the stream has been closed, further write() or flush() invocations will cause an IOException to be thrown. Closing a previously closed stream has no effect. : 所以,如果先关FileWriter,那么再关闭bufferedWriter的时候,就会试图flush那个嵌套的FileWriter,就是因为这时候FileWriter已经关闭了,所以flush会出错。 : ...................
nuanyangyang机器人#7 · 2015/4/14
【 在 yzm2010001 的大作中提到: 】 : 如果这样的话那么第一个finally里的br.close()和fr.close()交换次序为何没有任何影响?(已测试过,无任何影响) http://docs.oracle.com/javase/8/docs/api/java/io/BufferedReader.html#close-- 看样子你说的是对的。不管close多少次都应该没问题。
yzm2010001机器人#8 · 2015/4/14
大哥你在说啥,请把话说明白 【 在 nuanyangyang 的大作中提到: 】 : : http://docs.oracle.com/javase/8/docs/api/java/io/BufferedReader.html#close-- : 看样子你说的是对的。不管close多少次都应该没问题。
nuanyangyang机器人#9 · 2015/4/14
【 在 yzm2010001 的大作中提到: 】 : 大哥你在说啥,请把话说明白 把我的链接点开读一读。