一、IO流关闭顺序
代码示例:
public static void saveBase64(String data, String path, Long name) { OutputStreamWriter ops = null; BufferedWriter bw = null; File file; try { file = new File(path, name + ".txt"); ops = new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8); bw = new BufferedWriter(ops); bw.append("data:image/jpg;base64," + data); } catch (Exception e) { LOG.error(e.getMessage(), e); e.printStackTrace(); } finally { try {if (bw != null) { bw.flush(); bw.close(); } } catch (Exception e) { LOG.error(e.getMessage(), e); e.printStackTrace(); } } }
1.包装流(处理流)和节点流关闭
概念:
如果一个流的构造方法中需要传入流,那么这传入流称为“节点流”,此处的OutputStreamWriter就是节点流。
外部负责包装的流,称为:包装流,也可以叫做处理流,BufferedWriter就是包装流。
关闭:
包装流的关闭,只需要关闭包装流即可,包装流的close方法会自动将节点流也关闭。
2.按顺序关闭流
如果按顺序关闭流,是从内层流到外层流关闭还是从外层到内层关闭?
一般情况下是:先打开的后关闭,后打开的先关闭
另一种情况:看依赖关系,如果流a依赖流b,应该先关闭流a,再关闭流b
例如处理流a依赖节点流b,应该先关闭处理流a,再关闭节点流b
当然完全可以只关闭处理流,不用关闭节点流。处理流关闭的时候,会调用其处理的节点流的关闭方法
如果将节点流关闭以后再关闭处理流,会抛出IO异常;
二、try(){}语法含义
代码示例:
private static void saveBase64(String data, String path, Long name) { File file; file = new File(path, name + ".txt"); try (OutputStreamWriter ops = new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8); BufferedWriter bw = new BufferedWriter(ops)) { bw.append("data:image/jpg;base64,").append(data); } catch (Exception e) { LOG.error("保存图片异常:{}", e.getMessage()); } }
try块退出时,会自动调用res.close()方法,关闭资源。不用写一大堆finally来关闭资源。
所有实现Closeable的类声明都可以写在里面,最常见于流操作,socket操作,新版的httpclient也可以;
需要注意的是,try()的括号中可以写多行声明,每个声明的变量类型都必须是Closeable的子类,用分号隔开
参考: