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

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

  1. FileWriter writer = null;
  2. String file="D:\\test.txt";
  3. try{
  4. writer = new FileWriter(file);
  5. //某些处理后
  6. writer.flush();
  7. writer.close();
  8. }catch(Exception e){
  9. try {
  10. if(writer != null){
  11. writer.flush();
  12. writer.close();
  13. }
  14. } catch (IOException e1) {
  15. e1.printStackTrace();
  16. }
  17. }

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

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

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

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

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

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

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

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

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

  1. public void flush() throws IOException {
  2. synchronized (this.lock) {
  3. ensureOpen();
  4. implFlush();
  5. }
  6. }

再跟踪ensureOpen()方法:

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

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

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

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

  1. FileWriter writer = null;
  2. String file="D:\\test.txt";
  3. try{
  4. writer = new FileWriter(file);
  5. //某些处理后
  6. writer.flush();
  7. writer.close();
  8. }catch(Exception e){
  9. //nothing
  10. }finally{
  11. try {
  12. if(writer != null){
  13. writer.close();
  14. }
  15. } catch (IOException e1) {
  16. e1.printStackTrace();
  17. }
  18. }

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. (二)基于阿里云的MQTT远程控制(购买阿里云,在云端安装MQTT,测试MQTT远程通信)

    QQ名称为Friday~的网友把他自己买MQTT的过程截图发给了我,今天就说一下如何购买阿里云,安装MQTT可以参考 http://www.cnblogs.com/yangfengwu/p/77646 ...

  2. 第15章 RCC—使用HSE/HSI配置时钟

    第15章     RCC—使用HSE/HSI配置时钟 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku. ...

  3. 20155233 《网络对抗》Exp2 后门原理与实践

    实验过程 1.Win获得Linux Shell windows:使用ipconfig指令查看本机ip: windows:使用ncat命令打开监听: Linux反弹连接win: 输入 nc window ...

  4. 20155238 《JAVA程序设计》实验三(敏捷开发与XP实践)实验报告

    实验内容 敏捷开发与XP实践 XP基础 XP核心实践 相关工具 实验要求 1.没有Linux基础的同学建议先学习<Linux基础入门(新版)><Vim编辑器> 课程 2.完成实 ...

  5. 20155304《网络对抗》Exp4 恶意代码分析

    20155304<网络对抗>Exp4 恶意代码分析 实践内容 1.系统运行监控 1.1使用schtasks指令监控系统运行 我们在C盘根目录下建立一个netstatlog.bat的文本文件 ...

  6. 20155327 Exp9 Web安全基础

    20155327 Exp9 Web安全基础 基础问题回答 (1)SQL注入攻击原理,如何防御 SQL注入攻击就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器 ...

  7. 20155330 《网络攻防》 Exp3 免杀原理与实践

    20155330 <网络攻防> Exp3 免杀原理与实践 基础问题回答 杀软是如何检测出恶意代码的? 基于特征码.先对流行代码特征的提取,然后进行程序的比对,如果也检测到相应的特征码的程序 ...

  8. Oracle出现与并行相关的ORA-00600时的调查方法

    出现了 ORA-00600[kxfpqsod_qc_sod], 如何调查呢? 例如:从trace 文件的 Call Stack,可以看到 Error: ORA-600 [kxfpqsod_qc_sod ...

  9. 蓝牙disable流程简述

    蓝牙关闭的流程比打开流程要简单,主要就是一些profile的断连以及协议栈相关结构的释放. 这里简单说一下其流程,就直接从协议栈的disable的接口说起了. static int disable(v ...

  10. CSS快速入门-前端布局1(抽屉)

    一.效果图 前面对CSS基础知识有了一定的了解,是时候开始实战了!以下我对抽屉(https://dig.chouti.com/)主页进行模拟布局. 官方网站效果图: 模拟网站图: 二.实现步骤 1.整 ...