浅谈JavaIO之try with底层原理
IO关闭的问题
最近写了一个例子,读取一个文件没有问题,但是读取很多个文件就会告诉我:”Can't open so many files“,能帮我看看是什么问题吗?可能打开文件太多了吧,用两个命令,查看最大文件打开限制。
一个命令是
ulimit -a
第二个命令是
ulimit -n
256
看起来是最大文件限制太小了,只有256个,调大一点就可以了。
读文件都是一个一个读的,没有同时开这么多文件
好吧,看下写的代码吧:
BufferedReader bufferedReader = null; try { String line; bufferedReader = new BufferedReader(new FileReader("trywith/src/main/resources/www.flydean.com")); while ((line = bufferedReader.readLine()) != null) { log.info(line); } } catch (IOException e) { log.error(e.getMessage(), e); }
看完代码,问题找到了,IO没有关闭,应该在使用之后,在finally里面把你的reader关闭。
下面这段代码就行了:
BufferedReader bufferedReader = null; try { String line; bufferedReader = new BufferedReader(new FileReader("trywith/src/main/resources/www.flydean.com")); while ((line = bufferedReader.readLine()) != null) { log.info(line); } } catch (IOException e) { log.error(e.getMessage(), e); } finally { try { if (bufferedReader != null){ bufferedReader.close(); } } catch (IOException ex) { log.error(ex.getMessage(), ex); } }
使用try with resource
现在每段代码都要手动添加finally,实在是太麻烦了,很多时候又怕忘记关闭IO了,导致程序出现无法预料的异常。
从JDK7开始,Java引入了try with resource的新功能,把使用过后要关闭的resource放到try里面,JVM会帮你自动close的,是不是很方便,来看下面这段代码:
try (BufferedReader br = new BufferedReader(new FileReader("trywith/src/main/resources/www.flydean.com"))){ String sCurrentLine; while ((sCurrentLine = br.readLine()) != null){ log.info(sCurrentLine); } } catch (IOException e) { log.error(e.getMessage(), e); }
try with resource的原理
什么是resource呀?为什么放到try里面就可以不用自己close了?
resource就是资源,可以打开个关闭,我们可以把实现了java.lang.AutoCloseable接口的类都叫做resource。
先看下AutoCloseable的定义:
public interface AutoCloseable { void close() throws Exception; }
AutoCloseable定义了一个close()方法,当我们在try with resource中打开了AutoCloseable的资源,那么当try block执行结束的时候,JVM会自动调用这个close()方法来关闭资源。
我们看下上面的BufferedReader中close方法是怎么实现的:
public void close() throws IOException { synchronized (lock) { if (in == null) return; in.close(); in = null; cb = null; } }
自定义resource
那么我们是不是可以实现AutoCloseable来创建自己的resource呢?
我们定义这样一个resource类:
public class CustResource implements AutoCloseable { public void helpSister(){ log.info("解决问题!"); } @Override public void close() throws Exception { log.info("解决完问题,赶紧去吃饭!"); } public static void main(String[] args) throws Exception { try( CustResource custResource= new CustResource()){ custResource.helpSister(); } } }
运行输出结果
[main] INFO com.flydean.CustResource - 解决问题!
[main] INFO com.flydean.CustResource - 解决完问题,赶紧去吃饭!
以上就是浅谈JavaIO之try with底层原理的详细内容,更多关于JavaIO之try with底层原理的资料请关注我们其它相关文章!