【问题标题】:Java nio2 Directory is not closed. Causes "too many open files" error [closed]Java nio2 目录未关闭。导致“打开的文件太多”错误[关闭]
【发布时间】:2016-12-03 18:51:52
【问题描述】:

我正在使用这个创建很多用于批处理的临时目录:

Path tmp = Files.createTempDirectory("tmp-images");

该目录可能包含 1-50 个图像文件。我正在使用 Apache FileUtils 处理后删除目录:

FileUtils.deleteDirectory(tmp.toFile());

目录已删除,但我遇到“打开的文件太多”。 lsof 给了我这个:

java    DIR  253,0   6  136899239 /opt/tomcat/temp/tmp-images1570439806870910607 (deleted)
java    DIR  253,0   6  136899237 /opt/tomcat/temp/tmp-images2456811184361231168 (deleted)
java    DIR  253,0   6  136899237 /opt/tomcat/temp/tmp-images2456811184361231168 (deleted)
java    DIR  253,0   6  136899238 /opt/tomcat/temp/tmp-images8109733179118089091 (deleted)
java    DIR  253,0   6   69527104 /opt/tomcat/temp/tmp-images8763413559313243911 (deleted)
java    DIR  253,0   6  136927313 /opt/tomcat/temp/tmp-images8168355305097994981 (deleted)       

如何在没有打开文件句柄的情况下删除 nio2 临时目录?

【问题讨论】:

  • 我相信这意味着您正在泄漏打开的文件句柄。这些文件仍处于打开状态,因此无法完全删除。
  • 哪个操作系统?
  • 所有文件都已关闭。就是目录。
  • 你能贴出打开和关闭文件的完整代码吗?

标签: java linux file tomcat centos


【解决方案1】:

我发现了错误。我用过这个:

List<Path> result = Files.list(tmp).collect(Collectors.toList());

这会使目录打开两次!

正确的做法其实是这样的:

List<Path> result;
try(Stream<Path> stream = Files.list(tmp)){
    result = stream.collect(Collectors.toList());
}

java 文档:

返回的流封装了一个 DirectoryStream。如果需要及时处理文件系统资源,则应使用 try-with-resources 构造来确保在流操作完成后调用流的 close 方法。

【讨论】:

  • 我刚遇到同样的问题。这是一个糟糕的 API 设计,如果需要 try-with-resources,它不应该返回 Stream&lt;&gt;
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-22
  • 2017-09-09
  • 2016-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多