返回信息流/**
* 功能:记事本(界面+功能)
*/
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才执行的吗?为何会出流关闭错误(以后还要用到?)
这是一条镜像帖。来源:北邮人论坛 / java / #39976同步于 2015/4/14
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Java机器人发帖
io流文件关闭问题
yzm2010001
2015/4/14镜像同步12 回复
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
哪里有红色?
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)
我改了下,设置语法后不能再设置颜色......,只是想知道那个bw和fw不都是finally了吗,前面的流都执行完了,先关哪个有影响?为何先关fw会流关闭异常?莫非bw还要接收fw为参数,此时fw已被关闭,bw找不到fw,是不是这样?
【 在 nuanyangyang 的大作中提到: 】
: 哪里有红色?
: p.s. 要不要试试Java1.7的try-with-resource语句:
: [code=java]
: ...................
强!多谢
【 在 nuanyangyang 的大作中提到: 】
: 哪里有红色?
: p.s. 要不要试试Java1.7的try-with-resource语句:
: [code=java]
: ...................
【 在 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()了。
十分感谢,这是保存文件的时候出的异常(打开文件正常)(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会出错。
: ...................
如果这样的话那么第一个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会出错。
: ...................
【 在 yzm2010001 的大作中提到: 】
: 如果这样的话那么第一个finally里的br.close()和fr.close()交换次序为何没有任何影响?(已测试过,无任何影响)
http://docs.oracle.com/javase/8/docs/api/java/io/BufferedReader.html#close--
看样子你说的是对的。不管close多少次都应该没问题。
大哥你在说啥,请把话说明白
【 在 nuanyangyang 的大作中提到: 】
:
: http://docs.oracle.com/javase/8/docs/api/java/io/BufferedReader.html#close--
: 看样子你说的是对的。不管close多少次都应该没问题。