catch/finally中不应使用 writer.flush()
在开发中遇到了一个问题,关闭流的时候会出现某种莫名其妙的错误。后来一个巧合看到了这个解决方法。
先看问题(知道答案以后,才知道是这里出错了)
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()的更多相关文章
- Java异常处理中finally中的return会覆盖catch语句中的return语句
Java异常处理中finally中的return会覆盖catch语句中的return语句和throw语句,所以Java不建议在finally中使用return语句 此外 finally中的throw语 ...
- 一个问题:关于finally中return吞掉catch块中抛出的异常
今天遇到一个感觉很神奇的问题,记录一下问题以及自己分析问题的思路. 预警:不知道怎么看java字节码的朋友可能需要先看一下如何阅读java字节码才能看懂后面的解释. 我有一段程序: public cl ...
- try catch finally 中包含return的几种情况,及返回结果
当当当,兴致勃勃的第二篇博客,散花~ 下面是正题(敲黑板) 第一种情况:在try和catch中有return,finally中没有return,且finally中没有对try或catch中要 retu ...
- try catch finally 中 returne的执行顺序
结论:1.不管有没有出现异常,finally块中代码都会执行:2.当try和catch中有return时,finally仍然会执行:3.finally是在return后面的表达式运算后执行的(此时并没 ...
- try~Catch语句中异常的处理过程
[2014/10/12 21:40]文章待续~ 1.函数自身捕获处理异常的情况 以下的样例介绍了try~catch语句中出现异常时语句的运行顺序: package month10; import ja ...
- JAVA 之 每日一记 之 算法( 给定一个正整数,返回它在 Excel 表中相对应的列名称。 )
题目: 给定一个正整数,返回它在 Excel 表中相对应的列名称. 例如: 1 -> A 2 -> B 3 -> C ... 26 -> Z 27 -> AA 28 -& ...
- 从一次异常中浅谈Hibernate的flush机制
摘自http://www.niwozhi.net/demo_c70_i1482.html http://blog.itpub.net/1586/viewspace-829613/ 这是在一次事务提交时 ...
- 关于try...catch...finally中return的疑惑
原文:http://www.cnblogs.com/and_he/archive/2012/04/17/2453703.html 关于try...catch...finally里面的return一直是 ...
- 在try...catch语句中执行Response.End()后如何停止执行catch语句中的内容
在调用Response.End()时,会执行Thread.CurrentThread.Abort()操作. 如果将Response.End()放在try...catch中,catch会捕捉Thread ...
随机推荐
- 第18章 SysTick—系统定时器
第18章 SysTick—系统定时器 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/ ...
- always on 集群
准备工作 1. 四台已安装windows server 2008 r2 系统的虚拟机,配置如下: CPU : 1核 MEMORY : 2GB DISK : 40GB(未分区) NetAdapter ...
- 从源代码解释Android事件分发机制
在ViewRootImpl的setView方法中.用户的触摸按键消息是体如今窗体上的.而windowManagerService则是管理这些窗体,它一旦接收到用户对窗体的一些触摸按键消息,会进行对应的 ...
- 使用BAPI批量修改采购信息记录的税率
业务方面提出需求:由于国家税率从5月份开始16%更改为13%.要求开发一个批量修改采购信息记录税率的功能. 税代码就是税率,J2代表13% 这个需求在ME13里面就可以单个修改,所以可以用BDC,但后 ...
- 在testbench从文件读入激励
在验证verilog逻辑模块功能时候,我们可以从文件中读入激励,便于大规模的验证.文件中的数据我们可以用c++编写程序产生. 第一种读入文件的方法是用系统函数:$readmemb, readmemh, ...
- Cloud Container Service experimentation
Cloud Container Service experimentation K8S技术社区 举办云容器技术动手工作坊 活动时间:2018年1月13日(周六)13:30-17:30 活动地点:北京海 ...
- 20155218《网络对抗》Exp8 Web基础
20155218<网络对抗>Exp8 Web基础 1.基础问题回答 1.什么是表单? 表单是一个包含表单元素的区域,表单元素是允许用户在表单中(比如:文本域.下拉列表.单选框.复选框等等) ...
- 20155227《网络对抗》Exp8 Web基础
20155227<网络对抗>Exp8 Web基础 实验内容 (1)Web前端HTML (2)Web前端javascipt (3)Web后端:MySQL基础:正常安装.启动MySQL,建库. ...
- vim打开多窗口、多文件之间的切换
打开多个文件: 一.vim还没有启动的时候: 1.在终端里输入 vim file1 file2 ... filen便可以打开所有想要打开的文件 2.vim已经启动 输入 :e file 可以再打开一 ...
- 【php增删改查实例】第八节 - 部门管理模块(编写PHP程序)
首先,在同级目录新建一个query.php文件: 接着,去刷新页面,打开F12,NetWork,看看当前的请求能不能走到对应的php文件? 这就说明datagrid确实能够访问到query.php 只 ...