最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java中的FileInputStream是否需要close問題

 更新時間:2022年12月26日 09:46:30   作者:sleepybear1113  
這篇文章主要介紹了Java中的FileInputStream是否需要close問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

FileInputStream 類簡介

FileInputStream 類在 Java 中非常常用,用來讀取文件流的。而這種讀取方式往往會涉及到流的關(guān)閉 close。

如果不關(guān)閉 FileInputStream 流會有問題嗎?會導(dǎo)致內(nèi)存泄漏嗎?

FileInputStream 的 finalize() 方法

Java 中每個 Object 都有 finalize() 方法,用來在 gc 的時候調(diào)用。

而 FileInputStream 類中的 finalize() 方法中有一點特別的,它重寫了這個方法,并且在里面進(jìn)行了 close()。

如下代碼:

? ? /**
? ? ?* Ensures that the <code>close</code> method of this file input stream is
? ? ?* called when there are no more references to it.
? ? ?*
? ? ?* @exception ?IOException ?if an I/O error occurs.
? ? ?* @see ? ? ? ?java.io.FileInputStream#close()
? ? ?*/
? ? protected void finalize() throws IOException {
? ? ? ? if ((fd != null) && ?(fd != FileDescriptor.in)) {
? ? ? ? ? ? /* if fd is shared, the references in FileDescriptor
? ? ? ? ? ? ?* will ensure that finalizer is only called when
? ? ? ? ? ? ?* safe to do so. All references using the fd have
? ? ? ? ? ? ?* become unreachable. We can call close()
? ? ? ? ? ? ?*/
? ? ? ? ? ? close();
? ? ? ? }
? ? }

可以看到,只要觸發(fā)了 gc,那么就會調(diào)用 finalize() 方法,那么就會自動 close 流。當(dāng)被 close 之后,也就不會發(fā)生內(nèi)存泄漏了。

那么,不主動關(guān)閉,并且不主動觸發(fā) System.gc() 的話,它會被 JVM 回收嗎?

實際測試

為了更加直觀地看到是否調(diào)用了 finalize() 方法,這里新建一個 MyFileInputStream 類 extends FileInputStream,為的是重寫 FileInputStream 的 finalize() 方法,給里面加入一行打印輸出。

代碼如下:

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

/**
?* a class extends FileInputStream to test method finalize()
?*
?* @author sleepybear - https://blog.csdn.net/qq_36670734
?* @date 2022/1/9 21:02
?*/
public class MyFileInputStream extends FileInputStream {
? ? public MyFileInputStream(File file) throws FileNotFoundException {
? ? ? ? super(file);
? ? }

? ? /**
? ? ?* 重寫了 finalize 方法,把父類的 finalize 中的方法復(fù)制到此處,并且在其中添加打印信息
? ? ?*
? ? ?* @throws IOException 異常
? ? ?*/
? ? @Override
? ? protected void finalize() throws IOException {
? ? ? ? if ((this.getFD() != null) && (this.getFD() != FileDescriptor.in)) {
? ? ? ? ? ? /* if fd is shared, the references in FileDescriptor
? ? ? ? ? ? ?* will ensure that finalizer is only called when
? ? ? ? ? ? ?* safe to do so. All references using the fd have
? ? ? ? ? ? ?* become unreachable. We can call close()
? ? ? ? ? ? ?*/
? ? ? ? ? ? close();
? ? ? ? ? ? System.out.println("finalize and close");
? ? ? ? } else {
? ? ? ? ? ? System.out.println("only call finalize");
? ? ? ? }
? ? }
}

可以看到,只要執(zhí)行了 finalize() 方法,那么就會打印一行 “finalize”。

然后新建測試類,如下代碼:

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

/**
?* 測試 MyFileInputStream 的 Finalize
?*
?* @author sleepybear - https://blog.csdn.net/qq_36670734
?* @date 2022/1/9 21:10
?*/
public class TestFinalize {
? ? /**
? ? ?* 計數(shù)
? ? ?*/
? ? public static int count = 0;

? ? public static void main(String[] args) throws InterruptedException {
? ? ? ? listFiles("D://Work//");
? ? ? ? System.out.println("遍歷結(jié)束,等待 2 秒");
? ? ? ? TimeUnit.MILLISECONDS.sleep(1000 * 2L);
? ? ? ? System.out.println("顯式調(diào)用 gc");
? ? ? ? System.gc();
? ? ? ? TimeUnit.MILLISECONDS.sleep(1000 * 2L);
? ? ? ? System.out.println("結(jié)束");
? ? }

? ? /**
? ? ?* 遞歸遍歷所有文件,若遍歷到 2000 的整數(shù)倍,那么輸出這個文件的 md5
? ? ?*
? ? ?* @param path 路徑
? ? ?*/
? ? 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()) {
? ? ? ? ? ? // 遇到文件夾,往里面繼續(xù)遞歸
? ? ? ? ? ? File[] files = file.listFiles();
? ? ? ? ? ? if (files != null && files.length > 0) {
? ? ? ? ? ? ? ? for (File dir : files) {
? ? ? ? ? ? ? ? ? ? listFiles(dir.getAbsolutePath());
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? }

? ? ? ? if (file.isFile()) {
? ? ? ? ? ? // 遇到是文件,那么計數(shù) +1
? ? ? ? ? ? count++;
? ? ? ? ? ? if (count % 2000 == 0) {
? ? ? ? ? ? ? ? // 如果是 2000 的整數(shù)倍,那么打印文件的 md5,md5 打印需要用到 commons-codec-1.15.jar
? ? ? ? ? ? ? ? try {
? ? ? ? ? ? ? ? ? ? // 這里直接 new MyFileInputStream 并沒有顯式 close,同時工具方法里面也沒有調(diào)用 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();
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? }
? ? }
}

運行代碼,得到如下的結(jié)果:

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
遍歷結(jié)束,等待 2 秒
顯式調(diào)用 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

結(jié)論

上述測試可以看到,即使沒有主動 close 流,MyFileInputStream 類(或者是 FileInputStream 類)在結(jié)束之后,也會自動被回收。在回收的時候調(diào)用 finalize() 方法自行 close 流。

所以在使用 FileInputStream 類,不顯式調(diào)用 close 方法的話,一般不會造成內(nèi)存泄漏。

會有其他問題嗎

不主動 close 流的話,文件句柄還占用著,如果 JVM 沒有及時清理這些流的話,那么可能導(dǎo)致資源泄露問題,可能會因為過多打開文件導(dǎo)致 CPU 和 RAM 占用居高,甚至無法再打開新的文件進(jìn)行讀寫。

主動 close 的方式

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

當(dāng) Java 1.7 之后,可以使用 try-with-resources 方式自動 close 流

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

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • MybatisPlus使用Wrapper實現(xiàn)條件查詢功能

    MybatisPlus使用Wrapper實現(xiàn)條件查詢功能

    這篇文章主要介紹了MybatisPlus使用Wrapper實現(xiàn)查詢功能,使用它可以實現(xiàn)很多復(fù)雜的查詢,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-06-06
  • eclipse修改maven倉庫位置的方法實現(xiàn)

    eclipse修改maven倉庫位置的方法實現(xiàn)

    本文主要介紹了eclipse修改maven倉庫位置的方法實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • JavaWeb學(xué)習(xí)筆記之Filter和Listener

    JavaWeb學(xué)習(xí)筆記之Filter和Listener

    這篇文章主要給大家介紹了關(guān)于JavaWeb學(xué)習(xí)筆記之Filter和Listener的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • EditPlus運行java時從鍵盤輸入數(shù)據(jù)的操作方法

    EditPlus運行java時從鍵盤輸入數(shù)據(jù)的操作方法

    這篇文章主要介紹了EditPlus運行java時從鍵盤輸入數(shù)據(jù)的操作方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-03-03
  • Spring+SpringMVC+Hibernate整合實例講解

    Spring+SpringMVC+Hibernate整合實例講解

    在本篇文章里小編給大家整理的是關(guān)于Spring+SpringMVC+Hibernate整合實例講解,需要的朋友們可以學(xué)習(xí)下。
    2020-03-03
  • Springboot啟用多個監(jiān)聽端口代碼實例

    Springboot啟用多個監(jiān)聽端口代碼實例

    這篇文章主要介紹了Springboot啟用多個監(jiān)聽端口代碼實例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-06-06
  • Java序列化和反序列化_動力節(jié)點Java學(xué)院整理

    Java序列化和反序列化_動力節(jié)點Java學(xué)院整理

    把對象轉(zhuǎn)換為字節(jié)序列的過程稱為對象的序列化,把字節(jié)序列恢復(fù)為對象的過程稱為對象的反序列化。接下來通過本文給大家介紹Java序列化和反序列化及主要的兩種用途,感興趣的的友參考下吧
    2017-05-05
  • Java異常處理UncaughtExceptionHandler使用實例代碼詳解

    Java異常處理UncaughtExceptionHandler使用實例代碼詳解

    當(dāng)一個線程由于未捕獲異常即將終止時,Java虛擬機(jī)將使用thread . getuncaughtexceptionhandler()查詢線程的uncaughtException處理程序,并調(diào)用處理程序的uncaughtException方法,將線程和異常作為參數(shù)傳遞
    2023-03-03
  • SpringSessionRedis配置及發(fā)現(xiàn)的問題講解

    SpringSessionRedis配置及發(fā)現(xiàn)的問題講解

    今天小編就為大家分享一篇關(guān)于SpringSessionRedis配置及發(fā)現(xiàn)的問題講解,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-03-03
  • java并發(fā)包中CountDownLatch和線程池的使用詳解

    java并發(fā)包中CountDownLatch和線程池的使用詳解

    這篇文章主要介紹了java并發(fā)包中CountDownLatch和線程池的使用詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02

最新評論

金寨县| 华坪县| 河北区| 甘孜| 乌兰察布市| 东乡族自治县| 茂名市| 宜良县| 汝南县| 衡阳县| 神农架林区| 青神县| 锡林郭勒盟| 卢龙县| 贵溪市| 拜城县| 黑山县| 禹州市| 祥云县| 松原市| 光山县| 邻水| 特克斯县| 五华县| 通江县| 凤庆县| 甘孜县| 页游| 涞水县| 洱源县| 宜兰县| 黔东| 嘉义市| 苗栗县| 全南县| 郸城县| 成都市| 万年县| 伊宁县| 淮南市| 盐源县|