我必须关闭 FileInputStream 吗?

Posted

技术标签:

【中文标题】我必须关闭 FileInputStream 吗?【英文标题】:Do I have to close FileInputStream? 【发布时间】:2011-07-02 17:36:27 【问题描述】:

我是测试自动化领域的实习生。 我正在使用 Eclipse 创建 Junit 代码并使用 Eclipse 运行。 我正在使用 FileInputStream 函数从 excel 表中检索数据。

FileInputStream fi=new FileInputStream("c:\\search.xls");
Workbook w=Workbook.getWorkbook(fi);
Sheet s=w.getSheet(0);

是否需要关闭 Inputstream 功能?如果是这样,请指导我一些编码。

【问题讨论】:

【参考方案1】:

做这样的事情。

FileInputStream fi=null;
try
fi = new FileInputStream("c:\\search.xls");
Workbook w=Workbook.getWorkbook(fi);
Sheet s=w.getSheet(0);
catch(IOException ioe)
finally
if(fi != null)
fi.close();

fi = null;//This will be hint to get finalize() called on fi so that underlying resources used will released like files opened.

【讨论】:

【参考方案2】:

我这样做是为了确保关闭excel文件输入流,这可能会有所帮助

abstract int workWithWorkBook(Workbook workBook);

protected int doWorkBook(Path excelFile) throws IOException 
    File f = excelFile.toFile();

    try (FileInputStream excelContent = new FileInputStream(excelFile.toFile()))
        POIFSFileSystem fileSystem = new POIFSFileSystem(excelContent);
        Workbook workBook = null;
        if (f.getName().endsWith("xls")) 
            workBook = new HSSFWorkbook(fileSystem);
         else if (f.getName().endsWith("xlsx")) 
            workBook = new XSSFWorkbook(excelContent);
        
        return workWithWorkBook(workBook);

    catch (Exception e)
        e.printStackTrace();
        throw e;
    

9b9ea92b-5b63-47f9-a865-fd40dd602cd5

【讨论】:

【参考方案3】:

最近,当我尝试重构我的代码时,我不得不将工作簿的创建移至另一个方法,并在该方法中创建 FileInputStream。该方法创建一个 FileInputStream 并返回一个工作簿。但是 FileInputStream 在 main 方法中是不可见的;那么我将如何在主方法结束时关闭我的 FileInputStream 呢?答案是,您不必关闭 FileInputStream,而只需关闭工作簿,它会在内部关闭 FileInputStream。简而言之,说无论如何都必须关闭 FileInputStream 是不正确的。

【讨论】:

但是Workbook接口没有一个叫close的方法,如何关闭Workbook【参考方案4】:

是的!完成资源后,您应该始终释放资源。 Java 有一个强大的垃圾收集机制(请注意,它与资源管理/泄漏相比是不同的。) 所以垃圾收集器无法确定您将来是否需要资源?未能释放资源可能会导致诸如拒绝服务、性能不佳等问题。

正如已经回答的那样,但另一个省力的方法是try with resources

    try (FileInputStream fi = new FileInputStream("c:\\search.xls")) 

         //do something with fi.
         //fi.getChannel() ;

     catch(IOException e) 
        // exception handling.
     finally 
    // some statements for finally.
   

现在您不需要显式调用 fi.close() 方法。

【讨论】:

【参考方案5】:

是的,如果你想释放你的系统资源,你需要close输入流。

FileInputStream.close() 是您所需要的。

【讨论】:

在junit测试的情况下是否需要它?进程存在后不会释放资源吗? 是的,进程退出后,就没有什么可利用的了。因此,操作系统将回收资源。但想法是保持测试以稳定的方式运行,而不是等待出口完成工作。这就像在问“如果我关掉我的设备怎么办?” :-) 另外,它取决于操作系统。请在doesnt-the-jvm-release-all-the-resources-that-are-not-explicitly-closed-by-the-programmer 上查看此问题以了解更多详情【参考方案6】:

关闭您使用的资源总是一个好主意,但是

如果您在资源 B 中使用资源 A,则关闭 B 而不是 A 是明智的有一个方法。

在你的情况下,你在Workbook中使用FileInputStream,所以你最好关闭Workbook并依赖Workbok它将关闭FileInputStream

在这种特殊情况下,实际上,Workbook will close FileInputStreamgetWorkbook() 方法的末尾,但 close Workbook 仍然是一个好主意,以便能够被垃圾收集。

【讨论】:

【参考方案7】:

Basic CompSci 101 告诉我们确保关闭以 Java 或任何语言打开的资源。所以是的,你需要关闭它们。如果你不这样做,坏的juju必然会发生。

此外,您应该学习(并愿意)使用 Javadocs。查看 FileInputStream 和 Closeable 的 Javadoc。答案就在那里。

【讨论】:

盲目地遵循既定规则而没有批评和理解为什么?部分真的很糟糕。 坏事会发生——哦,很常见?!编程不是巫术魔法,没有提及未正确释放资源的后果(文件无法移动,通常可能会引入内存泄漏,os pool of file handles might be exausted)您的答案是无用的,而且是有害的. 投反对票。 噢,我用了一种语言,你说“ZOMG,他相信巫毒教”(而不是“hhhh,他没有把它拼出来,而是选择了一些白话。”相当多的其他回应没有说明后果,除非你出去否定他们,否则你只是在有偏见的高马上爬一堆肥皂盒。为什么我不拼写这些问题(以及为什么此主题中的大多数人没有)?因为它们很容易找到合适的文献,任何进行少量研究的人都可以使用。如果您认为不合适,请选择。【参考方案8】:

你要么需要close(),要么结束你的程序。

但是,如果您不关闭文件,您可能会遇到令人困惑的问题

有时单独运行测试或在同一进程中运行一组测试。 (所以你可以有一个测试,它可以以一种方式工作,但不能以另一种方式工作) 您不能重命名或删除打开的文件。

最佳做法是始终关闭已完成的资源,但是我将单元测试视为脚本,并不总是必须遵循最佳做法。

【讨论】:

关闭资源的充分理由。我会将too many open files 和内存泄漏添加到该列表中,尤其是对于长期存在的进程。 @Elist GC 之间需要很长时间,因为它们在清理时会关闭。 诚然,过程的长生命周期通常不是原因。更常见的是——递归读取文件/目录会导致too many open files。无论如何,这两种情况我自己都见过,所以无论触发因素是什么,这都是现实生活中的场景。【参考方案9】:
FileInputStream fi=null;
try 
    fi=new FileInputStream("c:\\search.xls");
    Workbook w=Workbook.getWorkbook(fi);
    Sheet s=w.getSheet(0);
 finally 
    if (fi!=null) 
        fi.close();
    

【讨论】:

只是一个小注释 - 您还需要用 try/catch 包装 close() 语句,因为 close() 声明抛出检查的 IOException。事实上,你不能像这样使用 finally。您只能尝试/最终使用运行时异常。但是对于像 IOException 和它的子类这样的检查异常,你必须有一个 try/catch 或一个 try/catch/finally ......它不会只用 try/finally 编译。 取决于是否为方法声明了 IOException。如果你抓住它,你应该知道如何处理它。重要的部分是将 close() 放在 finally 块中。事实上,对此的自动处理是我非常期待在 Java 7 中看到的特性之一。

以上是关于我必须关闭 FileInputStream 吗?的主要内容,如果未能解决你的问题,请参考以下文章

我必须关闭()每个 EntityManager 吗?

Dart:我必须取消 Stream 订阅并关闭 StreamSinks 吗?

从函数返回后文件会关闭吗?

有啥问题吗? [关闭]

将 inputStream 转换为 FileInputStream?

初识FileOutputStream与FileInputStream