zoukankan      html  css  js  c++  java
  • 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();
    	}
    }
  • 相关阅读:
    react native 学习资料整理
    yii cookie ,session 操作
    react native 的js 文件从哪里获取
    react native与现有的应用程序集成
    ubuntu 12.04 react-native 安装
    html ul li的学习
    CAGradientLayer的一些属性解析
    ubuntu 安装 swoole 和mac 安装swoole 扩展
    iOS React-Native入门指南之HelloWorld
    实现微信浏览器内打开App Store链接(已被和谐,失效了)
  • 原文地址:https://www.cnblogs.com/acm-bingzi/p/6400602.html
Copyright © 2011-2022 走看看