在开发中遇到了一个问题,关闭流的时候会出现某种莫名其妙的错误。后来一个巧合看到了这个解决方法。

先看问题(知道答案以后,才知道是这里出错了)

FileWriter writer = null;
String file="D:\\test.txt";
try{
writer = new FileWriter(file);
//某些处理后
writer.flush();
writer.close();
}catch(Exception e){
try {
if(writer != null){
writer.flush();
writer.close();
}
} catch (IOException e1) {
e1.printStackTrace();
}
}

碰巧看到的那段描述,如下:

方法可能因为checked exception导致清理流或资源失败 

这种方法可能无法清理(关闭,处置)流,数据库对象,或者其他的资源,需要一个明确的清除操作。

一般来说,如果一个方法打开一个流或其他资源,方法应该使用try/ finally块来保证流或资源清理方法返回之前。

这种错误模式在本质上是一样的OS_OPEN_STREAM和ODR_OPEN_DATABASE_RESOURCE错误模式,而是基于一个不同的(希望更好)静态分析技术。见韦默和Necula,查找和防止运行时错误处理错误,对分析技术的描述。

刚开始看到这段话,也是一脸懵逼,我明明在catch中使用了 writer.close() 方法了,为什么还说我没清理流。。。

想了好久才把注意力转移到这个flush()方法上:

FileWriter的flush()方法是从OutputStreamWriter中继承来的,其作用就是清空缓冲区并完成文件写入操作的

跟踪flush方法,一直到内部sun.nio.cs.StreamEncoder,找到其实现:

public void flush() throws IOException {
synchronized (this.lock) {
ensureOpen();
implFlush();
}
}

再跟踪ensureOpen()方法:

private void ensureOpen() throws IOException {
if (!this.isOpen)
throw new IOException("Stream closed");
}
}

终于找到了,原来这里会抛出异常。

我的理解是,同时使用write.flush();  write.close();两个方法。如果flush发生了异常,就会中断程序,把异常抛出来,就不会执行close方法。那么这个流实际上还是没有清理的。但是如果只使用write.close(); 那么会首先执行flush();,即使执行过程中flush发生了异常,也不会抛出来,还是会close的。

所以我最终的解决方案是:在catch/finally中不使用write.flush();,只是用write.close();

FileWriter writer = null;
String file="D:\\test.txt";
try{
writer = new FileWriter(file);
//某些处理后
writer.flush();
writer.close();
}catch(Exception e){
//nothing
}finally{
try {
if(writer != null){
writer.close();
}
} catch (IOException e1) {
e1.printStackTrace();
}
}

catch/finally中不应使用 writer.flush()的更多相关文章

  1. Java异常处理中finally中的return会覆盖catch语句中的return语句

    Java异常处理中finally中的return会覆盖catch语句中的return语句和throw语句,所以Java不建议在finally中使用return语句 此外 finally中的throw语 ...

  2. 一个问题:关于finally中return吞掉catch块中抛出的异常

    今天遇到一个感觉很神奇的问题,记录一下问题以及自己分析问题的思路. 预警:不知道怎么看java字节码的朋友可能需要先看一下如何阅读java字节码才能看懂后面的解释. 我有一段程序: public cl ...

  3. try catch finally 中包含return的几种情况,及返回结果

    当当当,兴致勃勃的第二篇博客,散花~ 下面是正题(敲黑板) 第一种情况:在try和catch中有return,finally中没有return,且finally中没有对try或catch中要 retu ...

  4. try catch finally 中 returne的执行顺序

    结论:1.不管有没有出现异常,finally块中代码都会执行:2.当try和catch中有return时,finally仍然会执行:3.finally是在return后面的表达式运算后执行的(此时并没 ...

  5. try~Catch语句中异常的处理过程

    [2014/10/12 21:40]文章待续~ 1.函数自身捕获处理异常的情况 以下的样例介绍了try~catch语句中出现异常时语句的运行顺序: package month10; import ja ...

  6. JAVA 之 每日一记 之 算法( 给定一个正整数,返回它在 Excel 表中相对应的列名称。 )

    题目: 给定一个正整数,返回它在 Excel 表中相对应的列名称. 例如: 1 -> A 2 -> B 3 -> C ... 26 -> Z 27 -> AA 28 -& ...

  7. 从一次异常中浅谈Hibernate的flush机制

    摘自http://www.niwozhi.net/demo_c70_i1482.html http://blog.itpub.net/1586/viewspace-829613/ 这是在一次事务提交时 ...

  8. 关于try...catch...finally中return的疑惑

    原文:http://www.cnblogs.com/and_he/archive/2012/04/17/2453703.html 关于try...catch...finally里面的return一直是 ...

  9. 在try...catch语句中执行Response.End()后如何停止执行catch语句中的内容

    在调用Response.End()时,会执行Thread.CurrentThread.Abort()操作. 如果将Response.End()放在try...catch中,catch会捕捉Thread ...

随机推荐

  1. 3D Touch开发技巧的笔记

    iPhone6s以及iPhone6s plus搭载iOS9,有一个新功能叫做3D Touch,这个功能有很大的用处,关键是要会用,这给交互方式又多了一个新的选择和思考,比如说游戏中的额外控制选项.绘图 ...

  2. javaee_SSH

    这是javaee课程的第六个实验ssh sturts2+sping 3+hibernate 现予以记录整个过程,以防遗忘 1. 2. 3. 4. 5.输入mvnrepository.com进入-> ...

  3. activiti发布APP时报错:关联的流程无效

    解决办法: 1.检查流程命名和任务命名以及其他命名中是否有特殊字符,有一些字符是不支持的.(中文是可以的,中文标点符号可能不行,我的经验是顿号会报错) 2.检查流程图,把鼠标放到每一根连接线上,观察它 ...

  4. 20155226《网络攻防》 Exp5 MSF基础应用

    20155226<网络攻防> Exp5 MSF基础应用 基础问题回答 1.用自己的话解释什么是exploit,payload,encode? exploit : Exploit的英文意思就 ...

  5. 20155229《网络对抗技术》Exp9:Web安全基础

    实验内容 Webgoat实践下相关实验. 实验步骤 WebGoat: Webgoat是OWASP组织研究出的一个专门进行web漏洞实验的应用品台,这个平台里包含了web中常见的各种漏洞,例如:跨站脚本 ...

  6. Linux日记Day3---Linux的文件属性与目录配置

    Linux最优秀的地方之一,就在于它的多用户.多任务环境.为了让用户具有较安全的管理机制,文件的权限管理是很重要的.Linux通常将文件的访问方式分为分为三个类别,分别是owner/group/oth ...

  7. vs编译器好多下划波浪线但不报错

    解决办法:项目属性->c/c++->常规->附加包含目录->$(ProjectDir): $(ProjectDir) 项目的目录(定义形式:驱动器 + 路径):包括尾部的反斜杠 ...

  8. C++ STL 学习笔记__(8)map和multimap容器

    10.2.9 Map和multimap容器 map/multimap的简介 ²  map是标准的关联式容器,一个map是一个键值对序列,即(key,value)对.它提供基于key的快速检索能力. ² ...

  9. 微信小程序之用户信息授权 wx.getUserInfo

    用户授权 <button open-type="getUserInfo" bindgetuserinfo='getUser'>授权用户信息</button> ...

  10. jenkis +sonarqube 对后端代码静态扫描,钉钉群通知执行结果(记录)

    代码提交,触发后端sonar测试,测试完成,jenkins触发依赖任务,执行python脚本,达到预期,调用上线任务模块,进行上线,达不到预期,钉钉群通知. 牵涉到配置: 1.配置sonar测试任务 ...