小师妹学JavaIO之:try with和它的底层原理

简介: 小师妹学JavaIO之:try with和它的底层原理

目录



简介


小师妹是个java初学者,最近正在学习使用java IO,作为大师兄的我自然要给她最给力的支持了。一起来看看她都遇到了什么问题和问题是怎么被解决的吧。


IO关闭的问题


这一天,小师妹一脸郁闷的问我:F师兄,我学Java IO也有好多天了,最近写了一个例子,读取一个文件没有问题,但是读取很多个文件就会告诉我:”Can't open so many files“,能帮我看看是什么问题吗?


更多内容请访问www.flydean.com


小师妹的要求当然不能拒绝,我立马响应:可能打开文件太多了吧,教你两个命令,查看最大文件打开限制。


一个命令是 ulimit -a


image.png


第二个命令是


ulimit -n
256


看起来是你的最大文件限制太小了,只有256个,调大一点就可以了。


小师妹却说:不对呀F师兄,我读文件都是一个一个读的,没有同时开这么多文件哟。


好吧,看下你写的代码吧:


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


过了半个小时 ,小师妹又来找我了,F师兄,现在每段代码都要手动添加finally,实在是太麻烦了,很多时候我又怕忘记关闭IO了,导致程序出现无法预料的异常。你也知道我这人从来就怕麻烦,有没有什么简单的办法,可以解决这个问题呢?


那么小师妹你用的JDK版本是多少?


小师妹不好意思的说:虽然最新的JDK已经到14了,我还是用的JDK8.


JDK8就够了,其实从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的原理


太棒了,小师妹非常开心,然后又开始问我了:F师兄,什么是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


小师妹恍然大悟:F师兄,那么我们是不是可以实现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 - 解决完问题,赶紧去吃饭!


总结


最后,小师妹的问题解决了,我也可以按时吃饭了。


本文的例子https://github.com/ddean2009/learn-java-io-nio

相关文章
|
5月前
|
算法 Java 程序员
探索代码之美——从小白到大牛的编程旅程深入理解Java中的异常处理机制
【8月更文挑战第29天】编程,一门看似神秘而复杂的艺术,实则充满无限可能与创造的乐趣。本文将带你走进编程的世界,从最初的迷茫与困惑,到逐步掌握编程思维,再到深入理解代码背后的哲学,一起见证一个编程小白如何成长为技术大牛的奇妙旅程。
全到哭!从面试到架构,阿里大佬用五部分就把高并发编程讲清楚了
不知道大家最近去面试过没有?有去面试过的小伙伴应该会知道现在互联网企业招聘对于“高并发”这块的考察可以说是越来越注重了。基本上你简历上有高并发相关经验,就能成为企业优先考虑的候选人。其原因在于,企业真正需要的是能独立解决问题的人才。每年面试找工作的人很多,技术水平也是高低不一,而并发编程却一直是让大家很头疼的事情,很多人总觉得自己似乎掌握了并发编程的知识,但实际在面试或者工作中,都会被它吊打虐哭。
146 0
直击灵魂!美团大牛手撸并发原理笔记,由浅入深剖析JDK源码
并发编程这四个字想必大家最近都在网上看到过有很多的帖子在讨论。我们都知道并发编程可选择的方式有多进程、多线程和多协程。在Java中,并发就是多线程模式。而多线程编程也一直是一个被广泛而深入讨论的领域。如果遇到复杂的多线程编程场景,大多数情况下我们就需要站在巨人的肩膀上利用并发编程框架——JDK Concurrent包来解决相关线程问题。
面试官:小伙子我们先来唠唠并发编程的几大核心知识点
并发编程算是Java的一个难点,经常做业务相关的程序员基本上用不到juc的包,但是这些知识点十分重要,所以不管在哪里,时刻保持学习真的很重要。
|
设计模式 Java 关系型数据库
85. 谈谈Java面向对象设计的六大原则,中高级面试常问
85. 谈谈Java面向对象设计的六大原则,中高级面试常问
131 0
|
关系型数据库 中间件 MySQL
分布式基础理论知识点-2pc协议(面试常问知识点)
分布式事务专题一直是面试的重点,这篇文章主要是讨论一下分布式事务中的2pc协议。如果你之前看过CAP和BASE理论,会对这篇文章的理解有更大的帮助。
391 0
分布式基础理论知识点-2pc协议(面试常问知识点)
听说你想学Java并发编程?先把这个学了(3)上
大家好,我是指北君。 这是AQS系列的第三篇文章,也是最后一篇,如果没看过AQS系列前两篇的童鞋,建议先去公号中的"Java并发编程"专栏中把前两篇看完。这篇主要是讲AQS是如何解决线程同步通信问题的。
听说你想学Java并发编程?先把这个学了(3)上