相信基于java io 编过程的朋友们,或多或少,都会遇到java.io.IOException: Stream closed这种异常。归根到底,是我们在关闭各种IO流的时候,没有注意到顺序。
下面,结合我对IO的理解,分析一下,究竟怎么样正确关闭。
读过jdk io 源码的朋友们应该知道,它使用了一种叫装饰器模式来组织类的。举个实例代码来说:
FileOutputStream fos = new FileOutputStream("f:\\william"); OutputStreamWriter osw = newOutputStreamWriter(fos); BufferedWriter bw = newBufferedWriter(osw); bw.write("hello world!");
下面,我把jdk中,BufferedWriter流关闭时的代码,展示给大家:
public void close() throws IOException { synchronized (lock) { if (out == null) { return; } try { flushBuffer(); //注意 } finally { out.close(); out = null; cb = null; } } } }
发现,原来在close一个流的时候,它会执行一次flush操作,因此,当把BufferedWriter.close()时,它会把自身的内容,一次性flush出去。如果此时OutputStreamWriter已经关闭了,那么BufferedWriter自身的内容流不出去,因此会抛出java.io.IOException: Stream closed。同理,OutputStreamWriter与FileOutputStream也一样道理。
正确关闭流的顺序是:
bw.close(); osw.close(); fos.close();
分析到此结束。