问题:
(1)JAVA的IO流使用了装饰模式,关闭最外面的流的时候会自动调用被包装的流的close()方吗?
(2)若是按顺序关闭流,是从内层流到外层流关闭仍是从外层到内存关闭?java
问题(1)解释: 设计模式
以下例子代码:
FileInputStream is = new FileInputStream(".");
BufferedInputStream bis = new BufferedInputStream(is);
bis.close();api
从设计模式上看:
java.io.BufferedInputStream是java.io.InputStream的装饰类。
BufferedInputStream装饰一个 InputStream 使之具备缓冲功能,is要关闭只须要调用最终被装饰出的对象的 close()方法便可,由于它最终会调用真正数据源对象的 close()方法。
BufferedInputStream的close方法中对InputStream进行了关闭,下面是jdk中附带的源代码:
java.io.BufferedInputStream的api:
close
public void close()throws IOException 关闭此输入流并释放与该流关联的全部系统资源。spa
所以,能够只调用外层流的close方法关闭其装饰的内层流,验证例子:设计
public static void main(String[] args) throws Exception {
FileOutputStream fos = new FileOutputStream("d:\\a.txt");
OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");
BufferedWriter bw = new BufferedWriter(osw);
bw.write("java IO close test");
bw.close();
}code
验证ok对象
问题(2)解释:若是不想使用(1)方式关闭流,能够逐个关闭流(可能你们比较习惯吧)内存
以下例子:
public static void main(String[] args) throws Exception {
FileOutputStream fos = new FileOutputStream("d:\\a.txt");
OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");
BufferedWriter bw = new BufferedWriter(osw);
bw.write("java IO close test");
//从内带外顺序顺序会报异常
fos.close();
osw.close();
bw.close();资源
}
报出异常:it
Exception in thread "main" 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.my.test.QQ.main(QQ.java:22)
以下例子:
public static void main(String[] args) throws Exception {
FileOutputStream fos = new FileOutputStream("d:\\a.txt");
OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");
BufferedWriter bw = new BufferedWriter(osw);
bw.write("java IO close test");
// 从外到内顺序关闭ok
bw.close();
osw.close();
fos.close();
}
验证ok
总结:
通常状况下是:先打开的后关闭,后打开的先关闭
另外一种状况:看依赖关系,若是流a依赖流b,应该先关闭流a,再关闭流b 例如处理流a依赖节点流b,应该先关闭处理流a,再关闭节点流b 固然彻底能够只关闭处理流,不用关闭节点流。处理流关闭的时候,会调用其处理的节点流的关闭方法 若是将节点流关闭之后再关闭处理流,会抛出IO异常;