我必须关闭 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 FileInputStream
在 getWorkbook()
方法的末尾,但 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 吗?的主要内容,如果未能解决你的问题,请参考以下文章
Dart:我必须取消 Stream 订阅并关闭 StreamSinks 吗?