我们想往一个文件里写东西,初始版本:
import java.io.*; class FileWriterDemo{ public static void main(String[] args) { FileWriter fw = new FileWriter("demo.txt"); //创建流,打开(如果不存在,新建)文件 fw.write("abcdefg"); //写入内容 fw.close(); /关闭流(关闭之前会flush()流) } }
但是以上三句话都会有异常——
第一句:
比如被写成了FileWriter fw = new FileWriter("ttt:\\demo.txt"),这显然是不对的,因为没有ttt这个盘符!
第二句:
写入内容过于庞大,整个电脑硬盘装不下,会有异常。
第三句:
如果流根本没有创建成功,则谈不上关闭。所以会有异常。
所以我们要进行try...catch...处理:
import java.io.*; class FileWriterDemo{ public static void main(String[] args) { try{ FileWriter fw = new FileWriter("demo.txt"); fw.write("abcdefg"); fw.close(); } catch (IOException e){ System.out.println("catch:"+e.toString()); } } }
这样处理还是不对!比如第二句异常了,则处理异常,那么fw.close()将不会执行,即资源没有被关闭,所以fw.close()这句话无论有没有异常都要执行,要将其放入try...catch...finally...的finally中:
class FileWriterDemo{ public static void main(String[] args) { try{ FileWriter fw = new FileWriter("demo.txt"); fw.write("abcdefg"); } catch (IOException e){ System.out.println("catch:"+e.toString()); } finally{ fw.close(); } } }
这样会编译报错,会说fw.close()的fw无法被找到,原因是fw是在try里面创建的,和finally属于不同的代码块,所以要将fw声明出去:
class FileWriterDemo{ public static void main(String[] args) { FileWriter fw = null; //外面声明 try{ fw = new FileWriter("demo.txt"); //里面创建 fw.write("abcdefg"); } catch (IOException e){ System.out.println("catch:"+e.toString()); } finally{ fw.close(); } } }
终于把fw弄得安分了。这样总可以了吧?不行!
把fw.close()放到finally里面之后,相当于这句话一定会被执行,但是这句话的异常没有被处理啊!因为我们把这句话从处理异常的try里面拿出来了,所以我们要重新try...catch一下:
class FileWriterDemo{ public static void main(String[] args) { FileWriter fw = null; //外面声明 try{ fw = new FileWriter("demo.txt"); //里面创建 fw.write("abcdefg"); } catch (IOException e){ System.out.println("catch:"+e.toString()); } finally{ try{ //在finally里面处理fw.close()的异常,再try一下 fw.close(); } catch (IOException e){ System.out.println(e.toString()); } } } }
终于编译通过了!!!
可是,仍然有不恰当的地方——
比如第一句写成FileWriter fw = new FileWriter("ttt:\\demo.txt"),不仅第一个try块会报异常,第二个try块(fw.close()所在的try块)也会报异常--java.lang.NullPointerException,原因是fw创建不成功,自然谈不上关闭,所以会被捕获异常,因此,在关闭之前判断一下会比较好,即:
if(fw!=null)
fw.close();
即finally块要写成这样:
finally{ try{ if(fw!=null) fw.close(); } catch (IOException e){ System.out.println(e.toString()); } }
或者是这样:
finally{ if(fw!=null) //先判断是否为空 try{ fw.close(); } catch (IOException e){ System.out.println(e.toString()); } }
终于OK了:
class FileWriterDemo{ public static void main(String[] args) { FileWriter fw = null; //外面声明 try{ fw = new FileWriter("demo.txt"); //里面创建 fw.write("abcdefg"); } catch (IOException e){ System.out.println("catch:"+e.toString()); } finally{ try{ //在finally里面处理fw.close()的异常,再try一下 if(fw!=null) fw.close(); } catch (IOException e){ System.out.println(e.toString()); } } } }