Java nio2目录未关闭.导致"打开文件太多"错误

kro*_*mit 5 java linux tomcat centos file

我使用这个为批处理创建了很多临时目录:

Path tmp = Files.createTempDirectory("tmp-images");
Run Code Online (Sandbox Code Playgroud)

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

FileUtils.deleteDirectory(tmp.toFile());
Run Code Online (Sandbox Code Playgroud)

该目录已删除,但我遇到"太多打开的文件".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)       
Run Code Online (Sandbox Code Playgroud)

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

kro*_*mit 13

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

List<Path> result = Files.list(tmp).collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

这使目录OPEN两次!

正确的方法实际上是这样的:

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

java doc:

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

  • 我刚刚遇到了同样的问题。这显然是糟糕的 API 设计,如果需要“try-with-resources”,它永远不应该返回“Stream&lt;&gt;”。 (2认同)