简介

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

IO关闭的问题

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

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

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

一个命令是 ulimit -a

第二个命令是

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

本文作者:flydean程序那些事

本文链接:http://www.flydean.com/io-try-with/

本文来源:flydean的博客

欢迎关注我的公众号:程序那些事,更多精彩等着您!

小师妹学JavaIO之:try with和它的底层原理的更多相关文章

  1. 小师妹学JavaIO之:Buffer和Buff

    目录 简介 Buffer是什么 Buffer进阶 创建Buffer Direct VS non-Direct Buffer的日常操作 向Buffer写数据 从Buffer读数据 rewind Buff ...

  2. 小师妹学JavaIO之:用Selector来发好人卡

    目录 简介 Selector介绍 创建Selector 注册Selector到Channel中 SelectionKey selector 和 SelectionKey 总的例子 总结 简介 NIO有 ...

  3. 小师妹学JavaIO之:目录还是文件

    目录 简介 linux中的文件和目录 目录的基本操作 目录的进阶操作 目录的腰疼操作 总结 简介 目录和文件傻傻分不清楚,目录和文件的本质到底是什么?在java中怎么操纵目录,怎么遍历目录.本文F师兄 ...

  4. 小师妹学JavaIO之:文件系统和WatchService

    目录 简介 监控的痛点 WatchService和文件系统 WatchSerice的使用和实现本质 总结 简介 小师妹这次遇到了监控文件变化的问题,F师兄给小师妹介绍了JDK7 nio中引入的Watc ...

  5. 小师妹学JavaIO之:文件File和路径Path

    简介 文件和路径有什么关系?文件和路径又隐藏了什么秘密?在文件系统的管理下,创建路径的方式又有哪些?今天F师兄带小师妹再给大家来一场精彩的表演. 文件和路径 小师妹:F师兄我有一个问题,java中的文 ...

  6. 小师妹学JavaIO之:NIO中Channel的妙用

    目录 简介 Channel的分类 FileChannel Selector和Channel DatagramChannel SocketChannel ServerSocketChannel Asyn ...

  7. 小师妹学JavaIO之:MappedByteBuffer多大的文件我都装得下

    目录 简介 虚拟地址空间 详解MappedByteBuffer MapMode MappedByteBuffer的最大值 MappedByteBuffer的使用 MappedByteBuffer要注意 ...

  8. 小师妹学JavaIO之:NIO中那些奇怪的Buffer

    目录 简介 Buffer的分类 Big Endian 和 Little Endian aligned内存对齐 总结 简介 妖魔鬼怪快快显形,今天F师兄帮助小师妹来斩妖除魔啦,什么BufferB,Buf ...

  9. 小师妹学IO系列文章集合-附PDF下载

    目录 第一章 IO的本质 IO的本质 DMA和虚拟地址空间 IO的分类 IO和NIO的区别 总结 第二章 try with和它的底层原理 简介 IO关闭的问题 使用try with resource ...

  10. 小师妹学JVM之:JIT中的PrintAssembly

    目录 简介 使用PrintAssembly 输出过滤 总结 简介 想不想了解JVM最最底层的运行机制?想不想从本质上理解java代码的执行过程?想不想对你的代码进行进一步的优化和性能提升? 如果你的回 ...

随机推荐

  1. python列表操作的大O效率

  2. 命令行解析parse.parse_know_args()

    简介 在接受到多余的命令行参数时不报错,只把第一个参数作为当前使用的命令参数, 剩余部分留给其它程序使用,返回一个tuple类型的命名空间和一个保存着余下的命令行字符的list 示例 import a ...

  3. django自定义模型管理器Manager及方法

    django自定义模型管理器Manager及方法 自定义管理器(Manager) 在语句Book.objects.all()中,objects是一个特殊的属性,通过它来查询数据库,它就是模型的一个Ma ...

  4. 合并区间(区间排序,vector的动态扩容的应用)

    以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] .请你合并所有重叠的区间,并返回一个不重叠的区间数组,该数组需恰好覆盖输入 ...

  5. 【LeetCode双指针】合并两个有序数组,从后向前遍历

    合并两个有序数组 https://leetcode.cn/problems/merge-sorted-array/ 给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m ...

  6. signature hdr data: BAD, no. of btyes(9088) out of range 问题排查与解决方案

    在使用yum工具安装gcc的时候,报出了signature hdr data: BAD, no. of btyes(9088) out of range 的问题 这是由于centos8中rpm工具存在 ...

  7. 记一次dockerfile无法构建问题追溯

    我有一个dockerfile如下: ENTRYPOINT ["/sbin/tini","-g", "--"] CMD /home/scrap ...

  8. Jmeter 如何连接mysql数据库?

    1 首先安装jmeter jdbc 插件 JDBC驱动包下载教程:https://blog.csdn.net/qq_50896685/article/details/129154801 2 安装好后将 ...

  9. CPNtools协议建模安全分析---实例变迁标记(五)

    之前的说了库所的标记,现在我们开始加讲变迁标记 1.描述变迁的标记有四种类型,分别是变迁的标记,门卫的标记,世间的标记,代码片段的标记. 咋变迁中限制更严格的输入token,其中Code Segeme ...

  10. HDFS分布式文件系统知识点梳理(一)

    HDFS分布式文件系统 一.HDFS简介 ​ HDFS是Hadoop Distribute File System,翻译成中文就是Hadoop 分布式文件系统,它是Hadoop的核心组成部分,是一个分 ...