广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Java中的FileInputStream是否需要close问题
  • 501
分享到

Java中的FileInputStream是否需要close问题

JavaFileInputStreamFileInputStreamcloseJavaFileInputStreamclose 2022-12-26 12:12:45 501人浏览 八月长安

Python 官方文档:入门教程 => 点击学习

摘要

目录FileInputStream 类简介FileInputStream 的 finalize() 方法实际测试结论会有其他问题吗主动 close 的方式总结FileInputStr

FileInputStream 类简介

FileInputStream 类在 Java 中非常常用,用来读取文件流的。而这种读取方式往往会涉及到流的关闭 close。

如果不关闭 FileInputStream 流会有问题吗?会导致内存泄漏吗?

FileInputStream 的 finalize() 方法

Java 中每个 Object 都有 finalize() 方法,用来在 GC 的时候调用。

而 FileInputStream 类中的 finalize() 方法中有一点特别的,它重写了这个方法,并且在里面进行了 close()。

如下代码:

    
    protected void finalize() throws ioException {
        if ((fd != null) &&  (fd != FileDescriptor.in)) {
            
            close();
        }
    }

可以看到,只要触发了 gc,那么就会调用 finalize() 方法,那么就会自动 close 流。当被 close 之后,也就不会发生内存泄漏了。

那么,不主动关闭,并且不主动触发 System.gc() 的话,它会被 JVM 回收吗?

实际测试

为了更加直观地看到是否调用了 finalize() 方法,这里新建一个 MyFileInputStream 类 extends FileInputStream,为的是重写 FileInputStream 的 finalize() 方法,给里面加入一行打印输出。

代码如下:

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;


public class MyFileInputStream extends FileInputStream {
    public MyFileInputStream(File file) throws FileNotFoundException {
        super(file);
    }

    
    @Override
    protected void finalize() throws IOException {
        if ((this.getFD() != null) && (this.getFD() != FileDescriptor.in)) {
            
            close();
            System.out.println("finalize and close");
        } else {
            System.out.println("only call finalize");
        }
    }
}

可以看到,只要执行了 finalize() 方法,那么就会打印一行 “finalize”。

然后新建测试类,如下代码:

import java.io.File;
import java.io.IOException;
import java.util.concurrent.TimeUnit;


public class TestFinalize {
    
    public static int count = 0;

    public static void main(String[] args) throws InterruptedException {
        listFiles("D://Work//");
        System.out.println("遍历结束,等待 2 秒");
        TimeUnit.MILLISECONDS.sleep(1000 * 2L);
        System.out.println("显式调用 gc");
        System.gc();
        TimeUnit.MILLISECONDS.sleep(1000 * 2L);
        System.out.println("结束");
    }

    
    public static void listFiles(String path) {
        if (path == null || path.length() == 0) {
            return;
        }

        File file = new File(path);
        if (!file.exists()) {
            return;
        }

        if (file.isDirectory()) {
            // 遇到文件夹,往里面继续递归
            File[] files = file.listFiles();
            if (files != null && files.length > 0) {
                for (File dir : files) {
                    listFiles(dir.getAbsolutePath());
                }
            }
        }

        if (file.isFile()) {
            // 遇到是文件,那么计数 +1
            count++;
            if (count % 2000 == 0) {
                // 如果是 2000 的整数倍,那么打印文件的 md5,md5 打印需要用到 commons-codec-1.15.jar
                try {
                    // 这里直接 new MyFileInputStream 并没有显式 close,同时工具方法里面也没有调用 close()
                    String md5 = org.apache.commons.codec.digest.DigestUtils.md5Hex(new MyFileInputStream(file));
                    System.out.println("count = " + count + ", md5 = " + md5);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

运行代码,得到如下的结果:

count = 2000, md5 = da6a56cda0772e7b321621472f1ca9ce
count = 4000, md5 = 8fc19cf5f7675179ed14abce784e29da
count = 6000, md5 = f93186d553b72e168f84ef9870285a17
count = 8000, md5 = 6af44868883a83b7ae4a0c3529ebc6ef
count = 10000, md5 = f570fdda290a62db840538c460e46510
count = 12000, md5 = 26ae171433b7c355223fa43f9d605110
count = 14000, md5 = c5f924cee8c51c19825af3713044b67a
count = 16000, md5 = deda72e7ef14674a49295f460301b4cf
count = 18000, md5 = 08753370d8c5bbda239e4d349892730c
count = 20000, md5 = df1213e1584803bf0a549c5a1c14f111
count = 22000, md5 = 9751d0dbc67c75cb446bdaf2d2434f66
count = 24000, md5 = 962cf50af21894734a78493e2f4df31b
count = 26000, md5 = f9556c74d758838e9c2202921de50056
count = 28000, md5 = 2a2699c13ff46dd34305bc5c7b780b52
count = 30000, md5 = 71af55db4adf6c7b2e667f031a809e91
count = 32000, md5 = bdef65ff9a12c5808b491f4b0be362d1
count = 34000, md5 = 9f1da8e150bfe5077c7ab82b3727aba0
count = 36000, md5 = 648422e1e6b89a1e331e407e6c7fc652
count = 38000, md5 = d1d9e7a656db7d0a4e79110fdb3f3462
count = 40000, md5 = 50b6c156bf30447d4f0b891677b75617
count = 42000, md5 = 1be6de12ec79e310675f1b1e5f1e891c
count = 44000, md5 = 027ca2c40a3D9b2d8f7818673cb6329c
count = 46000, md5 = 07e1a13fc5e3e5fdd3cacf998e57eaa8
count = 48000, md5 = c3bf74579b053ccdd5bb6bed7c8c5ab1
count = 50000, md5 = 78a2a70250a4df4f21523e0b94d6bca4
count = 52000, md5 = 769f5ea0d0a2c2b89d82a2bf2dbdbedd
count = 54000, md5 = c092d2f664c726da95f058018134bdfb
count = 56000, md5 = dc4d6f6ac6212f91d0aba93d692564c4
count = 58000, md5 = 217926c75b000f1dea20d319e9aeebbf
count = 60000, md5 = b437b7e80f6c52a42c3e4fe74be49c48
count = 62000, md5 = 9a92a6cf85e5513550ab801e12867dc9
count = 64000, md5 = b92bc3f149a121039aa8fe6a05f47b35
count = 66000, md5 = 064fd7ca2040cb21615e205b1f294e19
count = 68000, md5 = b4d20b20526769ef73702108c519cf25
count = 70000, md5 = 2436edd2550c69c1c2a519edfee2b853
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close
count = 72000, md5 = 6513a7abfe9f456814216f4040d82f2e
count = 74000, md5 = 7b1a34f38c218fa59b775543e1d2784f
count = 76000, md5 = 5e02f191cec09d5a938233dd43bec96d
count = 78000, md5 = 8e80d1b1e0c42af8937fc570e94145d4
count = 80000, md5 = 42c2b3d42c7966e47a1de23e3c89eca6
count = 82000, md5 = ce45fc5afea20d7e5a4fc79ddc3b04cb
count = 84000, md5 = 51bd1280db5b549968b855f7d25f7075
count = 86000, md5 = c90629033ec6b8fbfe5f17f63a44cfa3
count = 88000, md5 = 71b5e1bdc7f76444fb0fe88bc0e3a669
count = 90000, md5 = a930f1957f273fd5cb0d7fc984096ce4
count = 92000, md5 = badfe45e2c5917dcec2d0be1a03583de
count = 94000, md5 = 9e74b89c1f8e8ecfb00b84001b45DDD7
count = 96000, md5 = 7b4464b79280f9ac23e4b241508aa2d1
count = 98000, md5 = d79fabe6804056b0a6572e95f7c970c0
count = 100000, md5 = bcb8f86c91f8e106bdce40584ddba54b
count = 102000, md5 = 8f578f7a6dbcbde77d375a2e7c98ceee
count = 104000, md5 = aa39503815c583a38b409c92e04e5d14
count = 106000, md5 = 34ec7897529f1b00a78b13db223f907b
count = 108000, md5 = ea83e11ece4e7fdcc23bd9214f486ae3
count = 110000, md5 = 05d69a87ebf4133795aad1aae4a99ebb
count = 112000, md5 = bcc781b71ff6b10a57923af9fcc85b38
count = 114000, md5 = 5e468c6233db3f6a4311ebafa6e35eb6
count = 116000, md5 = 365a5b3af1dd522ed7c9a8b106f90224
count = 118000, md5 = 9117c65ed9ff083256a86af10ab88d65
count = 120000, md5 = 97f24779279cfe2fa1d573ef83c21009
count = 122000, md5 = ba6b12f0b76b192d9dd74965919bad95
count = 124000, md5 = b54c8105da76b3f13dcf78495bc2ff52
count = 126000, md5 = 648422e1e6b89a1e331e407e6c7fc652
count = 128000, md5 = eb115942b0abf38b881353debe4bdb92
count = 130000, md5 = e469a50bf7cfd9f1fb95f7d5badc1641
count = 132000, md5 = 2be1bd409def8cfc4f32a49af4bf5e9f
count = 134000, md5 = e3a20ac5df9d81a2ce301886fdfc0f07
count = 136000, md5 = 77269649674cc0fdf4b379a523a3a829
count = 138000, md5 = aead3fc8f945488ab71cf64271f46c54
count = 140000, md5 = e7098eafd97649e4a77edea89d0d22ab
count = 142000, md5 = 28d392b26bbd86fb3312960b82572060
count = 144000, md5 = f37ea0c388bec909255c602adc0cdfe4
count = 146000, md5 = d91659c455a4f66f9a16c8f287ce9fc9
count = 148000, md5 = 338364a0d43b018333d3143a466e1cf2
遍历结束,等待 2 秒
显式调用 gc
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close
finalize and close

结论

上述测试可以看到,即使没有主动 close 流,MyFileInputStream 类(或者是 FileInputStream 类)在结束之后,也会自动被回收。在回收的时候调用 finalize() 方法自行 close 流。

所以在使用 FileInputStream 类,不显式调用 close 方法的话,一般不会造成内存泄漏。

会有其他问题吗

不主动 close 流的话,文件句柄还占用着,如果 JVM 没有及时清理这些流的话,那么可能导致资源泄露问题,可能会因为过多打开文件导致 CPU 和 RAM 占用居高,甚至无法再打开新的文件进行读写。

主动 close 的方式

    FileInputStream fileInputStream = null;
    try {
        fileInputStream = new FileInputStream(file);
        fileInputStream.read();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (fileInputStream != null) {
            fileInputStream.close();
        }
    }

当 Java 1.7 之后,可以使用 try-with-resources 方式自动 close 流

    try (FileInputStream fileInputStream = new FileInputStream(file)) {
        fileInputStream.read();
    } catch (IOException e) {
        e.printStackTrace();
    }

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。

--结束END--

本文标题: Java中的FileInputStream是否需要close问题

本文链接: https://www.lsjlt.com/news/175807.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Java中的FileInputStream是否需要close问题
    目录FileInputStream 类简介FileInputStream 的 finalize() 方法实际测试结论会有其他问题吗主动 close 的方式总结FileInputStr...
    99+
    2022-12-26
    Java FileInputStream FileInputStream close Java FileInputStream close
  • Java需要注意的问题有哪些
    这篇文章主要介绍了Java需要注意的问题有哪些,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。Top 1:"abc"=="abc"返回的...
    99+
    2023-06-17
  • java方法重写时需要注意的问题
    目录注意事项1:子类权限控制符不能变小注意事项2:子类返回值类型只能变小注意事项3:抛出的异常类型只能变小注意事项4:方法名必须保持一致注意事项5:方法的参数类型和个数必须保持一致总...
    99+
    2022-11-12
  • Java泛型需要注意的问题有哪些
    这篇文章主要介绍“Java泛型需要注意的问题有哪些”,在日常操作中,相信很多人在Java泛型需要注意的问题有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java泛型需要注意的问题有哪些”的疑惑有所帮助!...
    99+
    2023-06-16
  • 在java中使用subList时需要注意哪些问题
    在java中使用subList时需要注意哪些问题?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。1. 使用Arrays.asList的注意事项1.1 可能会踩的坑先来看下Ar...
    99+
    2023-06-06
  • 在java中使用Sorted时需要注意哪些问题
    这期内容当中小编将会给大家带来有关在java中使用Sorted时需要注意哪些问题,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。Java是什么Java是一门面向对象编程语言,可以编写桌面应用程序、Web应用...
    99+
    2023-06-14
  • 在java中使用static时需要注意哪些问题
    在java中使用static时需要注意哪些问题?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。1、使用static方法的时候,只能访问static声明的属性和方法,而非stati...
    99+
    2023-06-06
  • LeetCode的Java路径问题:你需要知道的一切。
    LeetCode是一个知名的在线编程平台,旨在帮助程序员提升算法和数据结构的能力。在这个平台上,Java路径问题是一个经常出现的类型。如果你正在准备参加LeetCode的Java路径问题竞赛,那么本文将帮助你了解一切你需要知道的知识点。 J...
    99+
    2023-09-21
    path leetcode 响应
  • 在Java中实现Unix日志打包:需要注意的问题。
    在Java中实现Unix日志打包:需要注意的问题 在Unix系统中,日志文件是非常重要的资源,记录了系统的运行状态和事件。然而,随着时间的推移,这些日志文件可能会变得非常大,占用大量的磁盘空间。为了解决这个问题,Unix系统提供了一种称为“...
    99+
    2023-11-14
    unix 日志 打包
  • spring中@value注解需要注意的问题
    首先,@value需要参数,这里参数可以是两种形式:@Value("#{configProperties['t1.msgname']}")或者@Value("${t1.msgname}");其次,下面我们来看看如何使用这两形式,在配置上有什...
    99+
    2023-05-31
    spring 注解 ue
  • Java路径打包有哪些需要注意的问题?
    Java作为一种常用的编程语言,经常需要进行打包操作。在进行Java路径打包时,需要注意一些问题,以确保打包后的程序能够正常运行。下面将介绍一些Java路径打包需要注意的问题。 打包时需要注意的文件 在进行Java路径打包时,需要注意哪...
    99+
    2023-08-22
    path 打包 索引
  • 在java中使用修饰符需要注意哪些问题
    这篇文章给大家介绍在java中使用修饰符需要注意哪些问题,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。常用的java框架有哪些1.SpringMVC,Spring Web MVC是一种基于Java的实现了Web MVC...
    99+
    2023-06-14
  • JavaScript中10个需要掌握基础的问题是怎样的
    JavaScript中10个需要掌握基础的问题是怎样的,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。JavaScript 是一...
    99+
    2022-10-19
  • 面试中Java接口打包问题,你需要了解的重点!
    在Java开发中,我们经常需要将接口打包成jar包,并在其他项目中引用。但是在实际操作中,很多人都会遇到一些问题,比如打包后无法引用、引用后出现异常等。本文将详细介绍Java接口打包的相关知识,以及在面试中需要了解的重点。 一、什么是接口...
    99+
    2023-11-04
    接口 打包 面试
  • Java中的JavaScript路径打包:需要注意哪些安全问题?
    在Java开发中,经常需要使用JavaScript来实现前端的交互功能。而在Java中,为了方便管理和部署,我们通常会将JavaScript打包成一个文件,放在服务器上进行访问。但是,在进行路径打包时,需要注意一些安全问题,以避免出现潜在...
    99+
    2023-09-10
    打包 javascript path
  • MySQL中需要注意的字段长度问题
    在MySQL的表结构设计中,突然想起来几个地方碰到的问题比较多,大体来说一个就是字符集,一个就是数据类型。 而字符集和数据类型结合起来,就有一个蛮有意思的细节,那就是行长度的问题。 比如我们...
    99+
    2022-10-18
  • Java API 和 Django 实时开发中需要注意哪些问题?
    在现代软件开发中,Java API 和 Django 是两个非常流行的框架。Java API 是 Java 的应用程序接口,而 Django 是 Python 的一个 Web 框架。这两个框架在实时开发中都非常有用,但是开发人员在使用它们...
    99+
    2023-07-03
    api 实时 django
  • Java中使用异常处理时需要注意哪些问题
    这期内容当中小编将会给大家带来有关Java中使用异常处理时需要注意哪些问题,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。第1条: 只针对不正常的情况才使用异常建议:异常只应该被用于不正常的条件,它们永远不...
    99+
    2023-05-31
    java 异常处理 ava
  • Java编程算法是否需要关注关键字的框架?
    在Java编程中,算法的实现是程序员需要考虑的重要问题之一。而在实现算法时,是否需要关注关键字的框架则是一个有争议的问题。本文将探讨这个问题,并提供一些示例代码帮助读者更好地理解。 首先,让我们来了解一下什么是关键字的框架。在Java编程...
    99+
    2023-08-19
    编程算法 关键字 框架
  • JavaScript打包的问题:Java是否能够解决?
    随着前端技术的不断发展,JavaScript已经成为了前端开发的主要语言之一。在开发过程中,我们通常需要将多个JavaScript文件打包成一个文件,以便于网页加载。然而,这个过程并不总是那么顺利。在本文中,我们将探讨JavaScript...
    99+
    2023-08-18
    响应 打包 javascript
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作